I'm having trouble getting a composite primary key and foreign keys working in JPA 2/Hibernate. I'm trying to create a simple scenario with countries and provinces:
Country Entity:
@Entity
@Table(name = "country")
public class Country extends DomainObjectBase implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "code")
private String code;
@Basic(optional = false)
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
private List<Province> provinces;
}
Province Primary Key:
@Embeddable
public class ProvincePK implements Serializable {
@Basic(optional = false)
@Column(name = "code")
private String code;
@Basic(optional = false)
@Column(name = "country_code")
private String countryCode;
}
Province Entity:
@Entity
@Table(name = "province")
public class Province extends DomainObjectBase implements Serializable {
@EmbeddedId
protected ProvincePK provincePK;
@Basic(optional = false)
@Column(name = "name")
private String name;
@MapsId("country_code")
@JoinColumn(name = "country_code", referencedColumnName = "code", insertable = false, updatable = false)
@ManyToOne(optional = false)
private Country country;
}
This create the correct tables for me with one exception:
Country Table:
- code PK
- name
Province Table
- code PK FK - This is where the problem is its creating a foreign key reference to the country table's code column
- country_code FK This is the only foreign key reference I want
- name
How do I map my entities/composite key for hibernate to generate the schema I want? Right now I can't insert any data into province because its expecting that country contains the province code!
Thanks for any help.
Try this. I've found that it works for me when I work with data models like this.
@Entity
@Table(name = "province")
@IdClass(ProvincePK.class)
public class Province extends DomainObjectBase implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "code")
private String code;
@Id
@Basic(optional = false, insertable = false, updatable = false)
@Column(name = "country_code")
private String countryCode;
@Basic(optional = false)
@Column(name = "name")
private String name;
@JoinColumn(name = "country_code", referencedColumnName = "code")
@ManyToOne
private Country country;
}
@MapsID
argument must match to the name of attribute in ProvincePK
class. @JoinColumn
should be marked insertable=true,updatable=true
, then it works. Here is the code -
@Entity
@Table(name = "province")
public class Province implements Serializable {
@EmbeddedId
protected ProvincePK provincePK;
@Basic(optional = false)
@Column(name = "name")
private String name;
@MapsId(value = "country_code")
@JoinColumn(name = "country_code", referencedColumnName = "code")
@ManyToOne(optional = false)
private Country country;
}
@Embeddable
public class ProvincePK implements Serializable {
@Basic(optional = false)
@Column(name = "code")
private String code;
@Basic(optional = false)
@Column(name = "country_code")
private String country_code;
}
@Entity
@Table(name = "country")
public class Country implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "code")
private String code;
@Basic(optional = false)
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
private List<Province> provinces;
}
Hope it helps.
来源:https://stackoverflow.com/questions/4832544/jpa-2-foreign-key-that-only-includes-one-field-from-a-composite-primary-key