使用 hibernate/JPA 注释的多字段主键映射问题 [英] Mapping issue with multi-field primary keys using hibernate/JPA annotations

查看:19
本文介绍了使用 hibernate/JPA 注释的多字段主键映射问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被一个使用多字段主键的数据库困住了.我有一个情况,我有一个主表和详细信息表,其中详细信息表的主键包含的字段也是主表的外键.像这样:

I'm stuck with a database which is using multi-field primary keys. I have a situation where I have a master and details table, where the details table's primary key contains fields which are also the foreign key's the the master table. Like this:

Master primary key fields:
    master_pk_1

Details primary key fields:
    master_pk_1
    details_pk_2
    details_pk_3

在 Master 类中,我们像这样定义了 hibernate/JPA 注释:

In the Master class we define the hibernate/JPA annotations like this:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idGenerator")
@Column(name = "master_pk_1")
private long masterPk1;

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1")
private List<Details> details = new ArrayList<Details>();

在详细信息类中,我定义了 id 和反向引用,如下所示:

And in the details class I have defined the id and back reference like this:

@EmbeddedId
@AttributeOverrides( { 
        @AttributeOverride( name = "masterPk1", column = @Column(name = "master_pk_1")),
        @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")),
        @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")) })
private DetailsPrimaryKey detailsPrimaryKey = new DetailsPrimaryKey();

@ManyToOne
@JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1", insertable=false)
private Master master;

这一切的目的是我可以创建一个新的master,给它添加一些细节,当保存时,JPA/Hibernate会在masterPk1字段中为master生成新的id,并自动将它传递给详细信息记录,将其存储在 DetailsPrimaryKey 类中匹配的 masterPk1 字段中.至少这是我一直在查看的文档所暗示的.

The goal of all of this was that I could create a new master, add some details to it, and when saved, JPA/Hibernate would generate the new id for master in the masterPk1 field, and automatically pass it down to the details records, storing it in the matching masterPk1 field in the DetailsPrimaryKey class. At least that's what the documentation I've been looking at implies.

实际发生的是,hibernate 似乎正确地创建和更新数据库中的记录,但没有将密钥传递给内存中的详细信息类.相反,我必须自己手动设置.

What actually happens is that hibernate appears to corectly create and update the records in the database, but not pass the key to the details classes in memory. Instead I have to manually set it myself.

我还发现,如果没有将 insertable=true 添加到对 master 的反向引用,那么 hibernate 会创建在插入语句中两次列出 master_pk_1 字段的 sql,导致数据库抛出一个例外.

I also found that without the insertable=true added to the back reference to master, that hibernate would create sql that had the master_pk_1 field listed twice in the insert statement, resulting in the database throwing an exception.

我的问题是这种注释排列是否正确?或者有更好的方法吗?

My question is simply is this arrangement of annotations correct? or is there a better way of doing it?

推荐答案

您能否也添加 DetailsPrimaryKey 映射?

Could you add the DetailsPrimaryKey mapping also ?

在您的映射中似乎很奇怪的是,您将详细信息中的master_pk_1"列映射了两次.通过添加 insertable=false 选项,现在插入有效,但我猜更新仍然无效(实际上,当您在实体中多次映射列时,您必须使用 insertable=false, updatable=false 注释除其中之一之外的所有列)

What seems strange in your mapping is that you are mapping twice the 'master_pk_1' column in the details tale. By adding the insertable=false option, now inserting works, but i guess updates still not works (in fact when you map columns more than once in an entity you must annotate all but one of them with insertable=false, updatable=false)

为了纠正这个问题,我认为您应该将@ManyToOne Master 移到详细信息 id(删除 insertable=false 选项).

To correct that, i think you should move the @ManyToOne Master to the detail id (removing the insertable=false option).

您还应该将选项 mappingBy="detailsPrimaryKey.master" 添加到 @OneToMany 注释中,如果您希望自动保存孩子,也可以添加一个级联.

You should also add the option mappedBy="detailsPrimaryKey.master" to the @OneToMany annotation, and maybe also a cascade if you wish the childs to be automatically saved.

(看http://beavercreekconsulting.com/blog/2008/10/hibernate-annotations-for-a-one-to-many-mapping/ 你会看到一段代码解决了与你的问题非常相似的问题)

(look at http://beavercreekconsulting.com/blog/2008/10/hibernate-annotations-for-a-one-to-many-mapping/ you will see a code solving something quite similar to your problem)

这篇关于使用 hibernate/JPA 注释的多字段主键映射问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆