JPA 2 - 仅包含复合主键中的一个字段的外键?

时间:2011-01-28 20:06:19

标签: java jpa java-ee composite-key

我无法在JPA 2 / Hibernate中使用复合主键和外键。我正在尝试用国家和省份创建一个简单的场景:

国家/地区实体:

@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;
}

省主键:

@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;
}

省实体:

@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;
}

这为我创建了正确的表格,但有一个例外:

国家/地区表:

  1. 代码PK
  2. 名称
  3. 省表

    1. 代码PK FK - 这就是问题是它创建了对国家/地区表的代码列的外键引用
    2. country_code FK 这是我想要的唯一外键引用
    3. 名称
    4. 如何映射hibernate的实体/复合键以生成我想要的架构?现在我不能将任何数据插入省,因为它期望该国家/地区包含省代码!

      感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

试试这个。我发现当我处理这样的数据模型时,它对我有用。

@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;

}

答案 1 :(得分:0)

@MapsID参数必须与ProvincePK类中的属性名称匹配。 @JoinColumn应标记为insertable=true,updatable=true,然后才有效。这是代码 -

@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;
}

希望它有所帮助。