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

发布于 2024-10-14 19:57:22 字数 1410 浏览 5 评论 0原文

我在 JPA 2/Hibernate 中获取复合主键和外键时遇到问题。我正在尝试创建一个包含国家和省份的简单场景:

国家/地区实体:

@Entity
@Table(name = "country")
public class Country extends DomainObjectBase implements Serializable {

    @Id
    @Basic(optional = false)
    @Column(name = "code")
    private String code;

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

    @MapsId("country_code")
    @JoinColumn(name = "country_code", referencedColumnName = "code", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Country country;
}

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

国家/地区表:

  1. 代码 PK
  2. ...

省份表

  1. 代码 PK FK - < em>这就是问题所在,它创建了对国家/地区表的代码列的外键引用
  2. country_code FK 这是我想要的唯一外键引用
  3. ...

我如何映射我的hibernate 的实体/复合键生成我想要的架构?现在我无法将任何数据插入省份,因为它期望该国家/地区包含省份代码!

感谢您的任何帮助。

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;

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

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

  1. code PK
  2. ...

Province Table

  1. code PK FK - This is where the problem is its creating a foreign key reference to the country table's code column
  2. country_code FK This is the only foreign key reference I want
  3. ...

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空心↖ 2024-10-21 19:57:22

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

@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;
            
    @JoinColumn(name = "country_code", referencedColumnName = "code")
    @ManyToOne
    private Country country;
}

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;
            
    @JoinColumn(name = "country_code", referencedColumnName = "code")
    @ManyToOne
    private Country country;
}
绿萝 2024-10-21 19:57:22

@MapsID 参数必须与 ProvincePK 类中的属性名称匹配。 @JoinColumn 应该标记为 insertable=true,updatable=true,然后它就可以工作了。这是代码 -

@Entity
@Table(name = "province")
public class Province  implements Serializable {

    @EmbeddedId
    protected ProvincePK provincePK;

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

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
    private List<Province> provinces;
}

希望有帮助。

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

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

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
    private List<Province> provinces;
}

Hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文