PersistentObjectException:分离的实体传递给持久化-第二次运行方法时出现此异常

Posted

技术标签:

【中文标题】PersistentObjectException:分离的实体传递给持久化-第二次运行方法时出现此异常【英文标题】:PersistentObjectException: detached entity passed to persist - Got this exception when run method 2nd time 【发布时间】:2015-07-14 13:13:07 【问题描述】:

我第一次运行该方法时,它工作正常,对象被持久化。但第二次失败并给我例外:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: br.edu.ifpb.calendario.models.Usuario
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
br.edu.ifpb.calendario.dao.GenericDAO.persist(GenericDAO.java:29)
br.edu.ifpb.calendario.servlets.Calendarioservlet.cadastrarAnotacao(CalendarioServlet.java:122)
br.edu.ifpb.calendario.servlets.CalendarioServlet.doPost(CalendarioServlet.java:76)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

org.hibernate.PersistentObjectException: detached entity passed to persist: br.edu.ifpb.calendario.models.Usuario
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:442)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:266)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
br.edu.ifpb.calendario.dao.GenericDAO.persist(GenericDAO.java:29)
br.edu.ifpb.calendario.servlets.CalendarioServlet.cadastrarAnotacao(CalendarioServlet.java:122)
br.edu.ifpb.calendario.servlets.CalendarioServlet.doPost(CalendarioServlet.java:76)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

这是我向用户插入新注释的方法:

public void cadastrarAnotacao(HttpServletRequest request, HttpServletResponse response) throws ParseException, IOException 
    HttpSession session = request.getSession();
    Usuario usuario = (Usuario) session.getAttribute("usuario");
    AnotacaoDAO anotacaoDAO =  new AnotacaoDAO();
    Anotacao anotacao = new Anotacao();

    String mensagem = request.getParameter("mensagem");
    String dataString = request.getParameter("data");
    Date data = new SimpleDateFormat("yyyy-MM-dd").parse(dataString);

    anotacao.setData(data);
    anotacao.setMensagem(mensagem);
    anotacao.setUsuario(usuario);
    usuario.setAnotacao(anotacao);
    anotacaoDAO.persist(anotacao);
    anotacaoDAO.close();

    session.setAttribute("usuario", usuario);
    response.sendRedirect("calendario.do?op=eventos");

尝试执行以下行时会发生这种情况:

anotacaoDAO.persist(anotacao);

有什么建议吗? 提前致谢。

【问题讨论】:

【参考方案1】:

似乎您正在尝试持久化 anotacao,它具有对用户对象的引用,但用户对象本身并不由您的实体管理器管理,因此无法在数据库中指向它。尝试从数据库中提取用户对象,然后将 anotacao 的用户对象设置为该对象。

【讨论】:

以上是关于PersistentObjectException:分离的实体传递给持久化-第二次运行方法时出现此异常的主要内容,如果未能解决你的问题,请参考以下文章

org.hibernate.PersistentObjectException:分离的实体传递给坚持@ManyToOne

javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:分离的实体传递给坚持

JPA 级联持续存在并且对分离实体的引用会引发 PersistentObjectException。为啥?

org.hibernate.PersistentObjectException:传递给持久化的分离实体:多对一单向

JPA:传递给持久化的分离实体:嵌套异常是 org.hibernate.PersistentObjectException

Spring Data JPA:一对一实例化问题:PersistentObjectException:分离实体传递给持久化