1

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

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

会导致错误,而只是

em.find(entity.class, entitiy.getId())

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

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

编辑

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

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

2 回答 2

2

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

合并操作不会重新附加给定的实体。合并操作查找已加载的实体,由于找不到(因为您已将其分离),它从数据库加载实体并将提供的实体数据复制到数据库中的新副本上。

如果你做这样的事情:

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

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

myEntity = em.merge(myEntity);

现在 myEntity 将引用一个附加的实体(一个加载在第一级缓存中的实体,也就是持久性上下文)。

于 2014-11-10T12:09:00.890 回答
1

对不起我的错,是太快了。

看这里,很好的解释:

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

这是重要的句子:

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

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

于 2014-11-10T12:07:26.673 回答