java - not - 从JPA/EJB3持久性上下文中分离实体




spring data jpa和hibernate (10)

Mauricio Kanada,感谢你的建议,方法evict()效果很好。 我使用来自SEAM的JPA,内置了对JPA Entity Manager的支持,并且可以访问hibernate委托Session,因此这种方法“逐出”。

非常感谢,Zmicer

分离通过EntityManager获取的特定JPA实体Bean的最简单方法是什么? 或者,我可以让查询首先返回分离的对象,这样它们基本上可以作为“只读”吗?

我想要这样做的原因是因为我想修改bean中的数据 - 仅在我的应用程序中,但不会将其持久保存到数据库中。 在我的程序中,我最终必须在EntityManager上调用flush(),这将保留从附加实体到底层数据库的所有更改,但我想排除特定对象。


(可能为时已晚,无法回答,但对其他人有用)

我正在用JPA开发我的第一个系统。 不幸的是,当这个系统几乎完成时,我遇到了这个问题。

简单的说。 使用Hibernate,或等待JPA 2.0。

在Hibernate中,您可以使用'session.evict(object)'从会话中删除一个对象。 在JPA 2.0中, 现在在草案中有一个'EntityManager.detach(object)'方法将一个对象与持久化上下文分离。


在JPA 1.0(使用EclipseLink测试)中,您可以在事务之外检索实体。 例如,使用容器管理的事务,您可以:

public MyEntity myMethod(long id) {
    final MyEntity myEntity = retrieve(id);
    // myEntity is detached here
}

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public MyEntity retrieve(long id) {
    return entityManager.find(MyEntity.class, id);
}

处理类似的情况我创建了一个扩展持久化实体对象的DTO对象,如下所示:

class MyEntity
{
   public static class MyEntityDO extends MyEntity {}

}

最后,标量查询将检索所需的非托管属性:

(Hibernate) select p.id, p.name from MyEntity P
(JPA)       select new MyEntity(p.id, p.name) from myEntity P

如果你到这里是因为你真的想要通过远程边界传递一个实体,那么你只需要输入一些代码来欺骗hibernazi。

for(RssItem i : result.getChannel().getItem()){
}

Cloneable不会工作,因为它实际上复制了PersistantBag。

而忘记使用可序列化和bytearray流和管道流。 创建线程以避免死锁会破坏整个概念。


如果使用EclipseLink您还可以选择,

使用Query提示, eclipselink.maintain-cache"="false - 将分离所有返回的对象。

使用EclipseLink JpaEntityManager copy() API将对象复制到所需的深度。


我认为如果实体的主键没有被更改,你也可以使用方法EntityManager.refresh(Object o)。 此方法将恢复实体的原始状态。


据我所知,唯一直接的方法是:

  1. 提交txn - 可能不是一个合理的选择
  2. 清除持久化上下文 - EntityManager.clear() - 这是残酷的,但会清除它
  3. 复制对象 - 大多数时候你的JPA对象是可序列化的,所以这应该很容易(如果不是特别有效)。

这很快,很脏,但您也可以序列化和反序列化对象。


无论您使用哪种JPA实现,只需使用它现在在JPA 2.0中的entityManager.detach(object)和JEE6的一部分。





jpa