Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist

Using JPA with Hibernate, I got an exception when running the following code. The first time I run it, everything goes fine and the data is inserted in the database. The second time, when the data should be updated, it fails:

@AdminTx
public void processSite(Site site) {
    FluxBoutiqueMapping mapping = mapper.generateMappingFromUrl(site);

    Boutique boutique;
    for (FluxBoutiqueMapping.Boutique fluxBoutique : mapping.getListe().getBoutiques()) {
        log.error("Dans la boucle");
        boutique = daoAdmin.namedQuerySingle(Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());
        log.error("boutique : "+boutique);

        if (boutique==null) {
            log.error("Dans le new");
            boutique = new Boutique();
        }

        boutique.setSite(site);
        boutique.setUrlLogo(fluxBoutique.getLogo());
        boutique.setUrlBoutique(fluxBoutique.getUrl());
        boutique.setSelected(false);
        boutique.setIdWebSC(fluxBoutique.getId());
        boutique.setDateModification(new Date());

        boutiqueDao.persist(boutique);

        boutique = null;
    }
}

boutiqueDao.persist() simply calls the EntityManager.persist() method.

And here my Boutique class:

@Entity
@Table(name = "BOUTIQUE")
@SequenceGenerator(name = "SEQ_BOUTIQUE", sequenceName = "SEQ_BOUTIQUE")
@NamedQueries(value = {
        @NamedQuery(name = Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, query = "from Boutique b where b.idWebSC=?1"),
})
public class Boutique implements IPersistentObject, IPubliable<Manifestation> {

    /**
     * 
     */
    private static final long serialVersionUID = -3038903536445432584L;

    public static final String LOAD_BOUTIQUE_BY_IDWEBSC = "load.boutique.by.idwebsc";

    protected long idBoutique;

    protected Site site;

    protected Long idOrigine;

    protected String urlLogo;

    protected String urlBoutique;

    protected boolean selected;

    protected long idWebSC;

    protected Date datePublication;

    protected Date dateModification;

    @Override
    @Id
    @GeneratedValue(generator="SEQ_BOUTIQUE")
    @Column(name = "ID_BOUTIQUE", unique = true, nullable = false, precision = 8, scale = 0)
    public Long getId() {
        return this.idBoutique;
    }

    public void setId(Long idBoutique) {
        this.idBoutique = idBoutique;
    }

    @Override
    public void setIdOrigine(Long idOrigine) {
        this.idOrigine = idOrigine;
    }

    @Override
    @Column(name = "IDORIGINE", length = 7)
    public Long getIdOrigine() {
        return this.idOrigine;
    }

    @Override
    @Temporal(TemporalType.DATE)
    @Column(name = "DATE_PUBLICATION", length = 7)
    public Date getDatePublication() {
        return datePublication;
    }

    @Override
    public void setDatePublication(Date datePublication) {
        this.datePublication = datePublication;

    }

    @Override
    @Temporal(TemporalType.DATE)
    @Column(name = "DATE_MODIFICATION", length = 7)
    public Date getDateModification() {
        return dateModification;
    }

    public void setDateModification(Date dateModification) {
        this.dateModification = dateModification;
    }

    @Override
    public void update(Manifestation newer) {
        // TODO Auto-generated method stub

    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_SITE")
    @ForeignKey(name = "FK_BOUTIQUE_SITE")
    public Site getSite() {
        return site;
    }

    public void setSite(Site site) {
        this.site = site;
    }

    @Column(name = "URL_LOGO", length = 255)
    public String getUrlLogo() {
        return urlLogo;
    }

    public void setUrlLogo(String urlLogo) {
        this.urlLogo = urlLogo;
    }

    @Column(name = "URL_BOUTIQUE", length = 255)
    public String getUrlBoutique() {
        return urlBoutique;
    }

    public void setUrlBoutique(String urlBoutique) {
        this.urlBoutique = urlBoutique;
    }

    @Column(name = "SELECTED")
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    @Column(name = "ID_WEBSC", length = 7)
    public long getIdWebSC() {
        return idWebSC;
    }

    public void setIdWebSC(long idWebSC) {
        this.idWebSC = idWebSC;
    }

}

And finally, my stacktrace:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: fr.u2m.viparis.business.Boutique
        at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:219)
        at fr.u2m.dao.jpa.GenericDaoJPAImpl.persist(GenericDaoJPAImpl.java:60)
        at fr.u2m.viparis.service.impl.BoutiqueService.processSite(BoutiqueService.java:81)
        at fr.u2m.viparis.service.impl.BoutiqueService.processAllFluxBoutique(BoutiqueService.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
        at $Proxy136.processAllFluxBoutique(Unknown Source)
        at fr.u2m.viparis.fluxboutique.action.FluxBoutiqueAction.loadFlux(FluxBoutiqueAction.java:27)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:270)
        at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:187)
        at fr.u2m.struts.OpenViewRequestProcessor.processJpaActionPerform(OpenViewRequestProcessor.java:270)
        at fr.u2m.struts.OpenViewRequestProcessor.processActionPerform(OpenViewRequestProcessor.java:115)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
        at fr.u2m.struts.OpenViewRequestProcessor.process(OpenViewRequestProcessor.java:230)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
        at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.filter.MultiTabSessionFilter.doFilter(MultiTabSessionFilter.java:75)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.filter.MonitoringFilter.doFilter(MonitoringFilter.java:54)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.util.auditing.AuditingFilter.doFilter(AuditingFilter.java:44)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:71)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: fr.u2m.viparis.business.Boutique
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79)
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
        at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:213)
        ... 65 more

I'm running Java 7.0.11 on a Tomcat 7.0.32 server.

Any idea?

like image 271
Alexis Dufrenoy Avatar asked Mar 04 '13 09:03

Alexis Dufrenoy


People also ask

How do you resolve a detached entity passed to persist?

The solution is simple, just use the CascadeType. MERGE instead of CascadeType. PERSIST or CascadeType. ALL .

How to persist detached entity in jpa?

saveOrUpdate method, and its cousin Session. update, attach the passed entity to the persistence context while EntityManager. merge method copies the state of the passed object to the persistent entity with the same identifier and then return a reference to that persistent entity.

What is detached entity?

A detached entity is just an ordinary entity POJO whose identity value corresponds to a database row. The difference from a managed entity is that it's not tracked anymore by any persistence context. An entity can become detached when the Session used to load it was closed, or when we call Session.

What is persistence exception in Java?

public class PersistenceException extends RuntimeException. Thrown by the persistence provider when a problem occurs.


2 Answers

Persist is intended for brand new transient objects and it fails if the id is already assigned. You should probably call saveOrUpdate instead of persist.

Alternatively, you can check if the object is already contained in your entity manager, and if so do a

entityManager.merge(yourObject);

,else

entityManager.persist(yourObject);
like image 159
Raul Rene Avatar answered Oct 12 '22 07:10

Raul Rene


Your main problem is that you are loading entities in one DAO:

boutique = daoAdmin.namedQuerySingle(
    Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());

But then saving them with another:

boutiqueDao.persist(boutique);

In the case of existing entities this will generate a detached entity error, because the entity has an id, but does not exist in the unit of work of the second DAO. Of course, even if you had used the same DAO for read/persist, you would still run into problems because you are not supposed to use persist to save existing entities. Try this instead:

Read the entities using the same DAO as you are going to use to save them

boutique = boutiqueDAO.namedQuerySingle( Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());

Change your handling of new boutiques, to do an immediate persist of the object

if (boutique==null) {
    log.error("Dans le new");
    boutique = new Boutique();
    boutiqueDAO.persist(boutique);
}

Change the last persist to a merge

boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

boutique = boutiqueDao.merge(boutique);
like image 44
Perception Avatar answered Oct 12 '22 08:10

Perception