考虑一个Team
实体,其集合为Players
。 Team
映射允许级联合并和保存更新Players
。
我有一个Team
实体,数据库中有4个Players
。
我的服务允许用户指定Team
和Player
,然后执行以下操作:
Team
A Player
C并将其添加到Team
B 以上所有操作都在一个只执行数据库查询的事务中完成。它不会执行更新。
然后使用第二个事务将实体保存到数据库。但是,我不确定如何处理这个问题。
我现有的逻辑包含以下内容:
Team
B,这将有效地保存B队,然后合并到Player
C Player
C的版本号递增Team
答:但是,由于Hibernate会话的Team
实例仍然引用了旧Player
C的版本号,因此失败了。如何保存这两个实体?我是否必须单独保存Player
C并避免使用级联?
答案 0 :(得分:0)
在存储内容时,合并操作不应该是您的首选操作。它用于将分离的实体与实体管理器合并。非常简短地回顾一下对象可以使用JPA的不同状态(您可能需要阅读此内容):
对于Hibernate / JPA,瞬态和分离对象之间的区别在于它是否具有其id字段的值。
为了将对象存储在数据库中,该方法根据对象的状态而不同。
所以,有了这个基础,让我们来看看你在这里要做什么。
首先从EntityManager加载一个对象。鉴于您在事务的上下文中执行此操作,此对象在管理时。然后,复制对象,生成一个新的瞬态对象。然后,对这两个对象进行一些更改。
接下来,提交事务。然后,您的托管对象将被更新,而您的瞬态对象仍然是暂时的。然后,托管对象在事务中幸存,变得分离。然后存储瞬态对象,在这里你应该使用persist-method,而不是merge方法。如果有的话,为了更新你的分离对象(虽然它应该已经更新),你需要将它传递给merge-method。
因此,为了获得适当的级联形式Team to Player,您需要将persist和merge作为级联操作添加。
此外,在制作克隆对象时,请确保不要复制id,因为这会使它与所有Hibernate可以分辨的旧对象相同。
如果A队中的队员C和队B中的队员C有不同的版本号,则它不能是同一个对象。分离对象时可能会发生某些事情,导致两个团队中的玩家C不是同一个对象(但不确定这个......)