-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Persisting an entity referencing a detached object fails
PostPosted: Thu Apr 20, 2006 6:03 am 
Beginner
Beginner

Joined: Mon May 16, 2005 6:06 am
Posts: 20
Hibernate version:
Hibernate 3.2CR1, Hibernate Annotations 3.1 beta 9, Hibernate Entity Manager 3.1 beta7

Full stack trace of any exception that occurs:
When persisting a group object that references a detached user object the following error occurs.
Code:
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: test.PersistMergeTest$User
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:562)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:193)
   at test.PersistMergeTest.persist(PersistMergeTest.java:59)
   at test.PersistMergeTest.testPersistObjectWithDetachedObjectReference(PersistMergeTest.java:158)
   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 junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: test.PersistMergeTest$User
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:608)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:600)
   at org.hibernate.engine.CascadingAction$8.cascade(CascadingAction.java:202)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
   at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:290)
   at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
   at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:326)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:617)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:591)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:595)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:187)
   ... 17 more


Name and version of the database you are using:
MySQL 5.0.20

TestCase
Code:
package test;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;

import junit.framework.TestCase;

import org.hibernate.annotations.GenericGenerator;

public class PersistMergeTest extends TestCase
{
   private EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");;

   @Entity
   static class User
   {
      @Id
      @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
      String id;

      @ManyToOne(optional = true, fetch = FetchType.EAGER)
      Group group;
   }

   @Entity
   static class Group
   {
      @Id
      @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
      String id;

      @OneToMany(mappedBy = "group", fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST,
            CascadeType.MERGE, CascadeType.REFRESH})
      Set<User> users = new HashSet<User>();
   }

   private void persist(Object e) throws RuntimeException
   {
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = null;
      try
      {
         tx = em.getTransaction();
         tx.begin();
         em.persist(e);
         tx.commit();
      }
      catch (RuntimeException ex)
      {
         if (tx != null && tx.isActive()) tx.rollback();
         throw ex;
      }
      finally
      {
         em.close();
      }
   }

   private void merge(Object e) throws RuntimeException
   {
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = null;
      try
      {
         tx = em.getTransaction();
         tx.begin();
         em.merge(e);
         tx.commit();
      }
      catch (RuntimeException ex)
      {
         if (tx != null && tx.isActive()) tx.rollback();
         throw ex;
      }
      finally
      {
         em.close();
      }
   }

   /* FAILS */
   public void testPersistObjectWithDetachedObjectReference()
   {
      // instantiate and persist a user object
      User aUser = new User();
      persist(aUser);
      assertNotNull(aUser.id);

      // instantiate a group object
      Group aGroup = new Group();

      // assign the detached user object to the new group object
      aGroup.users.add(aUser);
      aUser.group = aGroup;

      // **************************************
      // the following statement will throw javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: test.UserEntity
      // **************************************
      persist(aGroup);
   }

   /* WORKS */
   public void testMergeObjectWithDetachedObjectReference()
   {
      // instantiate and persist a user object
      User aUser = new User();
      persist(aUser);
      assertNotNull(aUser.id);

      // instantiate and persist a group object
      Group aGroup = new Group();
      persist(aGroup);
      assertNotNull(aGroup.id);

      // assign the user to the group and merge the group object
      aGroup.users.add(aUser);
      aUser.group = aGroup;
      merge(aGroup);
   }
}


Is this the expected behaviour?

Any help is appreciated.

Regards, Johan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 27, 2006 9:49 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
yes that's expected. use merge if you have a graph of new / detached objects

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Re: PersistentObjectException: detached entity passed to per
PostPosted: Wed May 10, 2006 4:48 pm 
Newbie

Joined: Wed May 10, 2006 4:43 pm
Posts: 1
Location: Belo Horizonte
solution
replace entityManager.Persist(o) to EntityManager.merge(o);

Hermano Pereira
software architect
http://www.itsway.com.br

_________________
rgds,

Hermano Pereira
software architect
http://www.itsway.com.br


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.