【问题标题】:JPA detach and immediate merge causes errorsJPA 分离和立即合并导致错误
【发布时间】:2015-01-06 17:00:36
【问题描述】:

我正在使用 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)  

【问题讨论】:

  • 错误?想给人们一个线索,比如例外?
  • entity 是类还是对象?
  • EntityNotFoundException 对于另一个被删除的实体(在调用 em.find() 之前,仍在同一个事务中)。我说过如果需要我会详细说明:) Entity 是一个对象,entity.class 应该是 Entity.class)。
  • 我理解正确吗?您在调用 em.merge 时收到 EntityNotFoundException?那会更奇怪。

标签: java hibernate jpa entitymanager hibernate-entitymanager


【解决方案1】:

是不是你还在使用旧的实体引用而不是merge返回的那个?

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 将引用一个附加的实体(一个加载在第一级缓存中的实体,也就是持久性上下文)。

【讨论】:

    【解决方案2】:

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

    看这里,很好的解释:

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

    这句话很重要:

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

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

    【讨论】:

    • 就是这样!不敢相信这个没试过,错过了merge()的返回值,谢谢!
    猜你喜欢
    • 2012-03-15
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    相关资源
    最近更新 更多