JPA分离和立即合并会导致错误

时间:2014-11-10 11:39:12

标签: java hibernate jpa entitymanager hibernate-entitymanager

我正在使用JPA(Hibernate作为JPA提供程序)。我有一个删除实体的操作,似乎如果我分离实体并立即合并它就会抛出异常,即

em.find(entity.class, entitiy.getId())
em.detach(entity)
em.merge(entity)   
只需

就会导致错误
em.find(entity.class, entitiy.getId())

完美无瑕。关于分离和合并,我有什么遗漏吗?我没有对实体本身做任何事情,它没有改变,所以合并不应该改变任何东西。

如果需要,我可以详细说明我的具体案例。

修改

正如@rmertins指出的那样,我应该使用合并中的返回值,因为merge返回合并实体,而我们用作参数的实体保持分离。这有效:

em.find(entity.class, entitiy.getId())
em.detach(entity)
entity = em.merge(entity)  

2 个答案:

答案 0 :(得分:2)

是否仍然使用旧的实体引用而不是合并返回的引用?

The merge operation doesn't reattach the given entity。合并操作查找已经加载的实体,因为它找不到(因为你将它分离),它从数据库加载实体,并将提供的实体数据复制到数据库中的新副本。

如果您这样做:

MyEntity myEntity = em.find(MyEntity.class, myEntity.getId())
em.detach(myEntity);
em.merge(myEntity);

然后您只是丢弃实际的合并实体,因为您没有将myEntity重新分配给合并结果。你应该这样做:

myEntity = em.merge(myEntity);

现在myEntity将引用一个附加实体(在第一级缓存a.k.a持久化上下文中加载的实体)。

答案 1 :(得分:1)

对不起我的错,快点。

看这里,非常好的解释:

http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/

这是重要的句子:

  

这意味着在调用EntityManager.merge之后,我们必须使用   从该方法返回的实体引用代替原始引用   对象传入。

所以线索是合并后你的实体对象仍然是分离的,但是从merge中得到的对象副本再次附加到持久化上下文。