2.2.6. Mapping composite primary and foreign keys
Composite primary keys use a embedded class as the primary key representation, so you'd use the
@Id
and @Embeddable
annotations. Alternatively, you can use the @EmbeddedId
annotation. Note that the dependent class has to be serializable and implements equals()
/hashCode()
. You can also use @IdClass
as described in Section 2.2.3, “Mapping identifier properties”.
@Entity public class RegionalArticle implements Serializable { @Id public RegionalArticlePk getPk() { ... } } @Embeddable public class RegionalArticlePk implements Serializable { ... }
@Entity
public class RegionalArticle implements Serializable {
@Id
public RegionalArticlePk getPk() { ... }
}
@Embeddable
public class RegionalArticlePk implements Serializable { ... }
or alternatively
@Entity public class RegionalArticle implements Serializable { @EmbeddedId public RegionalArticlePk getPk() { ... } } public class RegionalArticlePk implements Serializable { ... }
@Entity
public class RegionalArticle implements Serializable {
@EmbeddedId
public RegionalArticlePk getPk() { ... }
}
public class RegionalArticlePk implements Serializable { ... }
@Embeddable
inherit the access type of its owning entity unless the Hibernate specific annotation @AccessType
is used. Composite foreign keys (if not using the default sensitive values) are defined on associations using the @JoinColumns
element, which is basically an array of @JoinColumn
. It is considered a good practice to express referencedColumnNames
explicitly. Otherwise, Hibernate will suppose that you use the same order of columns as in the primary key declaration.
@Entity public class Parent implements Serializable { @Id public ParentPk id; public int age; @OneToMany(cascade=CascadeType.ALL) @JoinColumns ({ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"), @JoinColumn(name="parentLastName", referencedColumnName = "lastName"), @JoinColumn(name="parentFirstName", referencedColumnName = "firstName") }) public Set<Child> children; //unidirectional ... }
@Entity
public class Parent implements Serializable {
@Id
public ParentPk id;
public int age;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumns ({
@JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
@JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
@JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
})
public Set<Child> children; //unidirectional
...
}
@Entity public class Child implements Serializable { @Id @GeneratedValue public Integer id; @ManyToOne @JoinColumns ({ @JoinColumn(name="parentCivility", referencedColumnName = "isMale"), @JoinColumn(name="parentLastName", referencedColumnName = "lastName"), @JoinColumn(name="parentFirstName", referencedColumnName = "firstName") }) public Parent parent; //unidirectional }
@Entity
public class Child implements Serializable {
@Id @GeneratedValue
public Integer id;
@ManyToOne
@JoinColumns ({
@JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
@JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
@JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
})
public Parent parent; //unidirectional
}
@Embeddable public class ParentPk implements Serializable { String firstName; String lastName; ... }
@Embeddable
public class ParentPk implements Serializable {
String firstName;
String lastName;
...
}
Note the explicit usage of the
referencedColumnName
.