在 merge() 操作中丢失复合外键(JPA/Hibernate)

Posted

技术标签:

【中文标题】在 merge() 操作中丢失复合外键(JPA/Hibernate)【英文标题】:Composite Foreign Key lost in merge() operation (JPA/Hibernate) 【发布时间】:2010-09-10 13:12:14 【问题描述】:

想象一个Employee 实体使用复合键引用Department

@Entity
public class Employee 
   ...
   @ManyToOne
   @JoinColumns(
      @JoinColumn(name="dept_country", referencedColumnName="country"),
      @JoinColumn(name="dept_id", referencedColumnName="id")
   )
   private Department dept;
   ...

在无状态会话 Bean 中,我通过设置适当的属性将 Employee 与 Department 关联起来:

employee.setAbc(abc);
System.out.println(entityManager.contains(aDepartment)));  //true
employee.setDepartment(aDepartment);
employee.setXyz(xyz);
entityManager.merge(employee);

=> 除了 部门之外,所有属性都已正确持久化(更新)到数据库中。

我想知道这是否与复合键有关,因为当我在后台查看Hibernate SQL时,恰好缺少那些外键列。

14:46:18 INFO  [STDOUT#write] Hibernate:
14:46:18 INFO  [STDOUT#write]     update
14:46:18 INFO  [STDOUT#write]         employees
14:46:18 INFO  [STDOUT#write]     set
14:46:18 INFO  [STDOUT#write]         abc=?,
14:46:18 INFO  [STDOUT#write]         xyz=?,
14:46:18 INFO  [STDOUT#write]     where
14:46:18 INFO  [STDOUT#write]         id=?

我希望我错过了一些琐碎的事情......

【问题讨论】:

DepartmentEmployees 的集合吗?请出示一下。 不,没有其他方向的参考。 (单向导航。)我编写了这个示例以尽可能简单地提出我的问题。实际上,实际上,我的复合键由更多列组成。但我希望这与现阶段无关,并且我犯了一个初级的错误......无论如何谢谢! 同样了不起:在 UnitTest 中它运行良好。我只在应用程序服务器中观察到问题,当它是无状态会话 Bean(JBoss6,Hibernate 3.5.0)的一部分时 @Jan 如果可能,请在解决问题时发布您自己的答案并告诉我。尝试改用属性访问策略 我当然会的。不幸的是,还没有解决方案。切换到属性访问策略没有帮助。不过还是谢谢你的建议。 【参考方案1】:

向我开枪!

正如我所提到的,我编写了上面的Employee/Department 代码 sn-p 来澄清我的情况。我不应该这样做!我省略了一个关键元素:updatable 标志

其实我的情况如下:

   @ManyToOne
   @JoinColumns(
      @JoinColumn(name="dept_country", referencedColumnName="country", insertable = false, updatable = false),
      @JoinColumn(name="dept_id", referencedColumnName="id", insertable = false, updatable = false)
   )

而且问题的答案相当明显:切换到updatable = true

对不起!

P.S:不过,我很困惑为什么它在我的单元测试中有效,而不是在应用服务器中

【讨论】:

以上是关于在 merge() 操作中丢失复合外键(JPA/Hibernate)的主要内容,如果未能解决你的问题,请参考以下文章

通过 PhpMyAdmin 的复合外键约束?

在 JPA 中使用继承时的复合外键问题

如何在hibernate中定义复合外键映射?

什么是mysql中的复合外键?

将复合键映射到两个外键

在 MySQL5 中添加复合外键失败