I need your help to map the relation in Hibernate of two tables using the @ElementCollection annotation.
The first one is the parent table
Table name: Parent
DB Columns
KEY1 Char (first primary key field)
KEY2 Char (second primary key field)
DESCRIPTION Char
DEPENDENTID BigInt
The second one is the dependent table
TableName: Dependent
DB Columns
PARENTID BigInt (first primary key field)
CODE Char (second primary key field)
FIELD1 Char
FIELD2 Char
I need to define the PK for both tables using @EmbeddedId annotation, so I have created the two classes:
@Embeddable
public class ParentPK implements Serializable
{
@Column(name="K1")
private String iK1;
@Column(name="K2")
private String iK2;
// I omit the constructor, getter, setter, equals, hashcode method
}
@Embeddable
public class DependentPK implements Serializable
{
@Column(name="PARENTID")
private String iParentId;
@Column(name="CODE")
private String iCode;
// I omit the constructor, getter, setter, equals, hashcode method
}
and then I've created the two beans:
The class for the DEPENDENT table.
Note that in this class I do not want to have any relational annotation
@Entity
@Table(name = "DEPENDENT")
public class DependentBean implements Serializable
{
@EmbeddedId
private DependentPK iDependentPK;
@Column(name = "FIELD1")
private String iField1;
@Column(name = "FIELD2")
private String iField2;
// I omit the constructor, getter, setter methods
}
And the class for the PARENT table
@Entity
@Table(name = "PARENT")
public class ParentBean implements Serializable
{
@EmbeddedId
ParentPK iParentPK;
@Column(name = "DESCRIPTION")
private String iDescription;
@Column(name = "DEPENDENTID")
private long iDependentId;
@ElementCollection
@CollectionTable(name="DEPENDENT", joinColumns={@JoinColumn(name="PARENTID", referencedColumnName="DEPENDENTID")})
private Set<DependentBean> iDependentBeans = new HashSet<DependentBean>();
// I omit the constructor, getter, setter methods
}
When I try to deploy I got the error:
Caused by: org.hibernate.MappingException: Foreign key (FK9619C2A17B05CB2:DEPENDENT [iDependentBeans_PARENTID,iDependentBeans_CODE])) must have same number of columns as the referenced primary key (DEPENDENT [PARENTID,iDependentBeans_PARENTID,iDependentBeans_CODE])
So I'm doing something wrong, but I can not imagine what. Could anyone wants to help me, please?
JPA 2.0 defines an ElementCollection mapping. It is meant to handle several non-standard relationship mappings. An ElementCollection can be used to define a one-to-many relationship to an Embeddable object, or a Basic value (such as a collection of String s).
The @ElementCollection is used to map non-entities (embeddable or basic) while @OneToMany is used to map entities. We need to use @Embeddable annotation to make an embeddable class(generally @Embeddable used with User defined class). When we say basic types that means String or any other wrapper classes.
Annotation Type ElementCollection. @Target(value={METHOD,FIELD}) @Retention(value=RUNTIME) public @interface ElementCollection. Defines a collection of instances of a basic type or embeddable class. Must be specified if the collection is to be mapped by means of a collection table.
I believe @ElementCollection is mainly for mapping non-entities (embeddable or basic) while @OneToMany is used to map entities. So which one to use depend on what you want to achieve.
@ElementCollection should be used with basic type or embeddable class, not for entity.
The DependentBean is an Entity.
Try to use One To Many Mapping and modify your schema
PARENT schema
KEY1 Char (PK)
KEY2 Char (PK)
DEPENDENTID BigInt (PK)
DESCRIPTION Char
DEPENDENT schema
CODE Char (PK)
PARENTID BigInt (FK)
KEY1 Char (FK)
KEY2 Char (FK)
FIELD1 Char
FIELD2 Char
One To Many mapping
ParentPK
@Embeddable
public class ParentPK {
@Column(name = "K1")
private String iK1;
@Column(name = "K2")
private String iK2;
@Column(name = "DEPENDENTID")
private long iDependentId;
}
ParentBean
@Entity
@Table(name = "PARENT")
public class ParentBean {
@EmbeddedId
ParentPK iParentPK;
@OneToMany(mappedBy = "parent")
List<DependentBean> iDependentBeans;
}
DependentBean
@Entity
@Table(name = "DEPENDENT")
public class DependentBean {
@Id
@Column(name = "CODE")
private String iCode;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "PARENTID", referencedColumnName = "iDependentId"),
@JoinColumn(name = "K1", referencedColumnName = "iK1"),
@JoinColumn(name = "K2", referencedColumnName = "iK2") })
ParentBean parent;
}
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