'Hibernate mapping exception with join table

I've been facing a mapping exception I simply don't understand. Here is the exception:

Caused by: org.hibernate.MappingException: Foreign key (FKCA2E919A5E0752D:cim10_indicationgroup_indicator [indicatorId])) must have same number of columns as the referenced primary key (cim10_indicationgroup [indicationGroupId,cim10Id])

The tables are as follows (notice already the discrepancy regarding the PK):

desc cim10_indicationgroup_indicator;
+-------------------------+---------+------+-----+---------+-------+
| Field                   | Type    | Null | Key | Default | Extra |
+-------------------------+---------+------+-----+---------+-------+
| cim10_indicationgroupId | int(11) | NO   | PRI | NULL    |       |
| indicatorId             | int(11) | NO   | PRI | NULL    |       |
+-------------------------+---------+------+-----+---------+-------+

desc cim10_indicationgroup;
+-------------------------+---------+------+-----+---------+-------+
| Field                   | Type    | Null | Key | Default | Extra |
+-------------------------+---------+------+-----+---------+-------+
| cim10_indicationGroupId | int(11) | NO   | PRI | NULL    |       |
| indicationGroupId       | int(11) | NO   | MUL | NULL    |       |
| cim10Id                 | int(11) | NO   | MUL | NULL    |       |
+-------------------------+---------+------+-----+---------+-------+

desc indicator;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| indicatorId | int(11)      | NO   | PRI | NULL    |       |
| indicator   | varchar(255) | NO   |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+

On Hibernate side, entities stand as follows:

@Entity
@Table(name = "cim10_indicationgroup")
@Immutable
public class Cim10IndicationGroupCouple {

   @Id
   @Column(name = "cim10_indicationGroupId")
   private Integer cim10IndicationGroupId;

   @Column(name = "indicationGroupId")
   private Integer indicationGroupId;

   @Column(name = "cim10Id")
   private Integer cim10Id;

   @ManyToMany
   @JoinTable(
      name = "cim10_indicationgroup_indicator",
      joinColumns = @JoinColumn(name = "indicatorId")
   )
   private Set<Indicator> indicators;

   // getters, setters, equals/hashcode

And the referenced entity:

@Entity
@Table(name = "indicator")
@Immutable
public class Indicator {

  @Id
  @Column(name = "indicatorId")
  private Integer id;

  @Column(name = "indicator")
  private String indicator;

   // getters, setters, equals/hashcode

As a bonus, here comes the metadata from the problematic join table:

SHOW KEYS FROM cim10_indicationgroup\G
*************************** 1. row ***************************
       Table: cim10_indicationgroup
  Non_unique: 0
    Key_name: PRIMARY
Seq_in_index: 1
 Column_name: cim10_indicationGroupId
   Collation: A
 Cardinality: 10137
    Sub_part: NULL
      Packed: NULL
        Null:
  Index_type: BTREE
     Comment:
*************************** 2. row ***************************
       Table: cim10_indicationgroup
  Non_unique: 0
    Key_name: cim10_indicationGroup_pk
Seq_in_index: 1
 Column_name: cim10Id
   Collation: A
 Cardinality: 10137
    Sub_part: NULL
      Packed: NULL
        Null:
  Index_type: BTREE
     Comment:
*************************** 3. row ***************************
       Table: cim10_indicationgroup
  Non_unique: 0
    Key_name: cim10_indicationGroup_pk
Seq_in_index: 2
 Column_name: indicationGroupId
   Collation: A
 Cardinality: 10137
    Sub_part: NULL
      Packed: NULL
        Null:
  Index_type: BTREE
     Comment:
*************************** 4. row ***************************
       Table: cim10_indicationgroup
  Non_unique: 1
    Key_name: fk_cim10_indicationGroup_indicationGroup
Seq_in_index: 1
 Column_name: indicationGroupId
   Collation: A
 Cardinality: 633
    Sub_part: NULL
      Packed: NULL
        Null:
  Index_type: BTREE
     Comment:

Why is there a mapping exception at all?



Solution 1:[1]

I think your @ManyToMany mapping is wrong. joinColumn specifies the column used to join the source entity ('Cim10IndicationGroupCouple') with join table, and inverseJoinColumn specifies the column used to join the target entity ('Indicator'). Try this

@ManyToMany
@JoinTable(
   name = "cim10_indicationgroup_indicator",
   joinColumns = {@JoinColumn(name = "cim10_indicationgroupId")}, 
   inverseJoinColumns={@JoinColumn(name="indicatorId")}
)
private Set<Indicator> indicators;

I agree that the exception is misleading, especially if this fixes it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Predrag Maric