composite PK/FK
danjourno Dec 29, 2005 12:58 AMI am trying to build a entity structure where I have a country table that uses ISO 3166 country codes as their PK, and a region table which also uses ISO3166 codes as a composite PK. For example.. a record in the country_region table that refers to New South Wales in Australia will have a primary key of:
country_code_1 = AU (FK value for country table)
region_code = NS
So in summary I have a CountryRegion table that has a many(regions) to one(country) relationship with a Country table. The key for the CountryRegion table is a composite of the country code and the region code.
I have referred to the wiki for this but am still a bit stuck on how to make this work.
I'll paste my code below.. If anyone could please look over an give me pointers as to where I'm going wrong I would be very grateful.
I have a Country entity, a CountryRegion entity, and an embeddable PK object called CountryRegion
The CountryRegion entity:
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.*;
//import java.util.List;
@Entity
@Table(name = "country_region")
public class CountryRegion implements Serializable {
java.lang.String name;
java.lang.String description;
CountryRegionPK pk;
public CountryRegion() {
}
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "regionCode", column = @Column(name = "region_code")),
@AttributeOverride(name = "country", column = @Column(name="country_code_1"))
})
public CountryRegionPK getPk() {
return pk;
}
public void setPk(CountryRegionPK pk) {
this.pk = pk;
}
@Column(name = "description")
public java.lang.String getDescription() {
return description;
}
public void setDescription(java.lang.String description) {
this.description = description;
}
@Column(name = "name")
public java.lang.String getName() {
return name;
}
public void setName(java.lang.String name) {
this.name = name;
}
}
The Country entity:
import java.io.Serializable;
import javax.persistence.*;
@Entity
@Table(name="country")
public class Country implements Serializable {
java.lang.String countryCode1;
java.util.List<Location> locations;
java.util.List<CountryRegion> countryRegion;
@Id
@Column(name="country_code_1")
public java.lang.String getCountryCode1() {
return countryCode1;
}
public void setCountryCode1(java.lang.String countryCode1) {
this.countryCode1 = countryCode1;
}
@OneToMany(fetch=FetchType.LAZY,mappedBy="country")
public java.util.List<Location> getLocations() {
return locations;
}
public void setLocations(java.util.List<Location> locations) {
this.locations = locations;
}
@OneToMany(fetch=FetchType.LAZY,mappedBy="country")
public java.util.List<CountryRegion> getCountryRegion() {
return countryRegion;
}
public void setCountryRegion(java.util.List<CountryRegion> countryRegion) {
this.countryRegion = countryRegion;
}
}
The Embedded primary key object:
import javax.persistence.Embeddable;
@Embeddable
public class CountryRegionPK implements java.io.Serializable{
private Country country;
private String regionCode;
public CountryRegionPK() {
super();
// TODO Auto-generated constructor stub
}
public CountryRegionPK(String regionCode, Country country)
{
this.regionCode = regionCode;
this.country = country;
}
public Country getCountry()
{
return country;
}
public void setCountry(Country country)
{
this.country = country;
}
public String getRegionCode()
{
return regionCode;
}
public void setRegionCode(String regionCode)
{
this.regionCode = regionCode;
}
public int hashCode()
{
return (int) country.hashCode() + regionCode.hashCode();
}
public boolean equals(Object obj)
{
if (obj == this) return true;
if (!(obj instanceof CountryRegionPK)) return false;
if (obj == null) return false;
CountryRegionPK pk = (CountryRegionPK) obj;
return pk.country.equals(country) && pk.regionCode.equals(regionCode);
}
An example of a referring entity (Location)
import java.io.Serializable;
import javax.persistence.*;
@Entity
@Table(name="location")
public class Location implements Serializable{
java.lang.Integer locationId;
java.lang.String city;
java.lang.String postalCode;
CountryRegion countryRegion;
Country country;
java.util.Date creationDate;
@Column(name="creation_date",nullable=false,updatable=false)
public java.util.Date getCreationDate() {
return creationDate;
}
public void setCreationDate(java.util.Date creationDate) {
this.creationDate = creationDate;
}
@Id(generate = GeneratorType.AUTO)
@Column(name="location_id")
public java.lang.Integer getLocationId() {
return locationId;
}
public void setLocationId(java.lang.Integer locationId) {
this.locationId = locationId;
}
@Column(name="city")
public java.lang.String getCity() {
return city;
}
public void setCity(java.lang.String city) {
this.city = city;
}
@ManyToOne
@JoinColumn(nullable=false, name="country_code_1")
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumns ( {@JoinColumn(nullable=false, name="region_code"),
@JoinColumn(nullable=false, name="country_code_1")})
public CountryRegion getCountryRegion() {
return countryRegion;
}
public void setCountryRegion(CountryRegion countryRegion) {
this.countryRegion = countryRegion;
}
@Column(name="postal_code")
public java.lang.String getPostalCode() {
return postalCode;
}
public void setPostalCode(java.lang.String postalCode) {
this.postalCode = postalCode;
}
}