org.hibernate.PersistentObjectException: detached entity passed to persist
可以这样解释该错误(ouf,如何在不描述Hibernate / JPA的整个对象生命周期的情况下执行此操作?):
使用JPA / Hibernate,您可以将类定义为
Entity。这意味着该类的对象可以由Hibernate管理,并因此存储在数据库中。
@Entitypublic class Entity { }当创建一个
Entity(
newEntity())类的新对象时,Hibernate对此一无所知。它不存储在数据库中,也不以任何方式受到Hibernate的控制。如果我们希望这些事情发生,我们需要
persist对象(
em.persist(entity))。当我们这样做时,对象状态存储在数据库中,而且对象本身也由Hibernate管理,这意味着Hibernate将跟踪对象的状态。另外,如果您已将Hibernate分配为生成ID,则将为该对象分配ID。
通过Hibernate从数据库加载对象时,该对象也将由Hibernate管理。一个新持久的对象或一个加载的对象都将具有一个ID,并且都将由Hibernate管理。但是,对象和Hibernate之间的连接可能会断开!发生这种情况时,对象变为
detached。一个
detached对象实际上只是一个
entity具有其ID设置的类的对象,但是不受Hibernate管理。
当涉及到一个
detached对象时,我们所拥有的选择不同于我们使用托管对象或新对象所具有的选择。与托管对象不同,
detached不允许将对象传递给
persist-method,因为它们已经具有ID,这意味着它们必须已经被持久保存了!当想要获取一个
detached对象并对其进行管理时,
merge-method是一种可以使用的方法。(http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#merge(T))
这会将合并的对象的状态与对应于对象ID的数据库状态合并。
merge使用新对象(不带id)进行调用将为其分配一个ID并保存,但要注意,它将对象作为参数传递时它不会做任何事情,而是会返回托管对象。
public Entity saveDetached(final Entity entity) { return em.merge(entity);}在您的情况下,解决方案将取决于一些因素,但是如果所引用的对象
Pagina始终是数据库中已经存在的对象,那么我只需
persist从中删除该操作的级联,并继续使用
em.persist()(
merge有其缺点。)可能是新的,有时您还需要添加一些逻辑来确定是否要持久化(持久化拥有的对象之前)。(我也觉得可能工作加载
Pagina并
Produto从数据库中,并将它们分配给新的
Pagina面前
persist。)
TL; DR
将
detached对象重新引入持久性上下文时,请使用
merge-方法
EntityManager,而不要使用
persist-方法。



