I have two entities which I would like to join through multiple columns. These columns are shared by an @Embeddable
object that is shared by both entities. In the example below, Foo
can have only one Bar
but Bar
can have multiple Foo
s (where AnEmbeddableObject
is a unique key for Bar
). Here is an example:
@Entity @Table(name = "foo") public class Foo { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "FOO_ID_SEQ", allocationSize = 1) private Long id; @Embedded private AnEmbeddableObject anEmbeddableObject; @ManyToOne(targetEntity = Bar.class, fetch = FetchType.LAZY) @JoinColumns( { @JoinColumn(name = "column_1", referencedColumnName = "column_1"), @JoinColumn(name = "column_2", referencedColumnName = "column_2"), @JoinColumn(name = "column_3", referencedColumnName = "column_3"), @JoinColumn(name = "column_4", referencedColumnName = "column_4") }) private Bar bar; // ... rest of class }
And the Bar class:
@Entity @Table(name = "bar") public class Bar { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "BAR_ID_SEQ", allocationSize = 1) private Long id; @Embedded private AnEmbeddableObject anEmbeddableObject; // ... rest of class }
Finally the AnEmbeddedObject
class:
@Embeddable public class AnEmbeddedObject { @Column(name = "column_1") private Long column1; @Column(name = "column_2") private Long column2; @Column(name = "column_3") private Long column3; @Column(name = "column_4") private Long column4; // ... rest of class }
Obviously the schema is poorly normalised, it is a restriction that AnEmbeddedObject
's fields are repeated in each table.
The problem I have is that I receive this error when I try to start up Hibernate:
org.hibernate.AnnotationException: referencedColumnNames(column_1, column_2, column_3, column_4) of Foo.bar referencing Bar not mapped to a single property
I have tried marking the JoinColumns are not insertable and updatable, but with no luck. Is there a way to express this with Hibernate/JPA annotations?
Annotation Type JoinColumn. Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply. (Optional) The SQL fragment that is used when generating the DDL for the column.
@Column annotation is used for Adding the column the name in the table of a particular MySQL database.
Annotation Type JoinTable. Specifies the mapping of associations. It is applied to the owning side of an association. A join table is typically used in the mapping of many-to-many and unidirectional one-to-many associations.
The usage of the isbn as the foreign key requires an additional @JoinColumn annotation. The referencedColumnName attribute tells Hibernate the name of the database column it shall use as the foreign key.
This worked for me . In my case 2 tables foo and boo have to be joined based on 3 different columns.Please note in my case ,in boo the 3 common columns are not primary key
i.e., one to one mapping based on 3 different columns
@Entity @Table(name = "foo") public class foo implements Serializable { @Column(name="foocol1") private String foocol1; //add getter setter @Column(name="foocol2") private String foocol2; //add getter setter @Column(name="foocol3") private String foocol3; //add getter setter private Boo boo; private int id; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "brsitem_id", updatable = false) public int getId() { return this.id; } public void setId(int id) { this.id = id; } @OneToOne @JoinColumns( { @JoinColumn(updatable=false,insertable=false, name="foocol1", referencedColumnName="boocol1"), @JoinColumn(updatable=false,insertable=false, name="foocol2", referencedColumnName="boocol2"), @JoinColumn(updatable=false,insertable=false, name="foocol3", referencedColumnName="boocol3") } ) public Boo getBoo() { return boo; } public void setBoo(Boo boo) { this.boo = boo; } } @Entity @Table(name = "boo") public class Boo implements Serializable { private int id; @Column(name="boocol1") private String boocol1; //add getter setter @Column(name="boocol2") private String boocol2; //add getter setter @Column(name="boocol3") private String boocol3; //add getter setter @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "item_id", updatable = false) public int getId() { return id; } public void setId(int id) { this.id = id; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With