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.  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Removing a detached instance (simple example don't work) !!!
PostPosted: Tue Jan 29, 2008 1:04 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Hi,

I have one simple test class for the most simple Person class, like this:

Code:
public PersonTest {
   private static EntityManagerFactory emFactory;
   private static EntityManager em;

   private Person person;

   @BeforeClass
   public static void init() {

      BasicConfigurator.configure();

      try {
         emFactory = Persistence.createEntityManagerFactory("punit");
         em = emFactory.createEntityManager();
      } catch(Exception e) {
         e.printStackTrace(); fail("Error");
      }

   }

   @Before
   public void beforeTest() {
      person = new Person();
      person.setId(1L);
      person.setName("John");
   }

   @Test
   public void Test() {
      // Write Object to database

      // Start transaction
      em.getTransaction().begin();
   
      person = em.merge(person);   <- It writes person object good in database

      // End transcation
      em.getTransaction().commit();   

      // Delete object

      // Start transaction
      em.getTransaction().begin();

      em.remove(person);      <- I GET AN EXCEPTION HERE !!!!

      // End transcation
      em.getTransaction().commit();   
      
   }
}


But, as you can see in the line above, where remove is called I get an exception:

Code:
java.lang.IllegalArgumentException: Removing a detached instance com.test.Person#1
   at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventListener.java:45)
   at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:86)
   at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:52)
   at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:766)
   at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:744)
   at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerIm


Why I get this exception, it is really wierd ?!

Thx in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 29, 2008 1:43 pm 
Beginner
Beginner

Joined: Mon Mar 07, 2005 6:23 pm
Posts: 21
edit: double post


Last edited by Clay on Tue Jan 29, 2008 1:45 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 29, 2008 1:44 pm 
Beginner
Beginner

Joined: Mon Mar 07, 2005 6:23 pm
Posts: 21
try em.merge(person) after you begin the new (second) transaction


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 29, 2008 2:38 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Why ?! I don't see reasonable explanation for that ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 29, 2008 4:37 pm 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
MilanMilanovich wrote:
Why ?! I don't see reasonable explanation for that ?

because your session is closed, what mean's Hibernate has forgotten this object as persistent one (=removed from the first level cache). You have to load it again into the session.

Carlo
-----------------------------
please give me credits if this post helped you.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 29, 2008 4:51 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
O.K. What method in this example closed the session ? And you want to say every time I merge my object, I need to load it again ?!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 3:21 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
MilanMilanovich wrote:
O.K. What method in this example closed the session ? And you want to say every time I merge my object, I need to load it again ?!


The Hibernate session (aka EntityManager's persistent context) is closed and invalidated after the commit(), because it is bound to a transaction. Your object goes into a detached status.
Indeed, if you reopen a new persistent context, your object isn't known as in a persistent state in this new context, so you have to merge it. Merge sees that your person object has a primary key (id), so it knows it is not new and must hit the database to reattach it.

Note, there is NO remove method which would just take a primary key (id) and a entity class as argument. You first need an object in a persistent state to be able to delete it.

BTW: if you want to work with Hibernate / JPA in a real project, get a good book (Bauer/King) and study the stuff.

Carlo
-----------------------------
please give me credits if this post helped you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 10:51 am 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Hi Carlof,

O.K. Thanks. But is there any way that my object keep to be in context after transaction is close ? I want write it, change it during work in my app and then on the end to save it ?

I have one more issue regarding this EntityManager "merge" method, which I asked here: http://forum.hibernate.org/viewtopic.php?t=983297.

Could you please help me with this ? It seems that merge returns copy of an object, but if that object contains some list or set it doesn't copy it by value but by reference, and the when I want to iterate through that objects' list, I got ConcurrentModificationException.

Thx in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 12:42 pm 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
MilanMilanovich wrote:
O.K. Thanks. But is there any way that my object keep to be in context after transaction is close ? I want write it, change it during work in my app and then on the end to save it ?

There is. JPA has a notion of a "Extended Persistent Context", which is best used in stateful session EJB holding an instance of EntityManager. A beast like this decouples transactional EJB methods from flushing the entities to the database. This last thing is only done when you invoke a method on that EJB which is annotated with @Remove, in which you have to close the EntityManager.

But for questions like these I have to repeat: read the Hibernate book from Bauer/King or some other good book.

Carlo
-----------------------------
please give me credits if this post helped you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 3:19 pm 
Beginner
Beginner

Joined: Mon Mar 07, 2005 6:23 pm
Posts: 21
I believe carlolf should get 2 (if not all) of the credits for doing the heavy lifting in this thread :)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 30, 2008 4:38 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Dear Carlof,

thank you. I have read the Java persistence with Hibernate book, reference documents and some tutorials and I still have some doubts.

Do you maybe know what can I do with copying object (with merge method), which contains list, because I get this ConcurrentModificationException when trying to iterate through list ?!

Thx.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 2:53 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
MilanMilanovich wrote:
Dear Carlof,

Do you maybe know what can I do with copying object (with merge method), which contains list, because I get this ConcurrentModificationException when trying to iterate through list ?!


You should show us some code so we can see when and what you are really doing in the iteration; what we can see in http://forum.hibernate.org/viewtopic.php?t=983297 is just not enough.

BTW, please remember:
Quote:
This posting has not been rated so far.


Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 7:54 am 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Dear Carlof,

I've tried to explain on the simpliest example here: http://forum.hibernate.org/viewtopic.php?t=983297, but if you need classes code, here it goes (again on the most simple example):

Class 1:

Code:
@javax.persistence.Entity
public class Class1 implements java.io.Serializable {

   private Long id;

   private java.util.Set<Class2> classes = new java.util.HashSet<Class2>();

   public Class1() {

   }

   @javax.persistence.Id
   @javax.persistence.GeneratedValue
   public Long getId() {
      return this.id;
   }   

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


   @javax.persistence.OneToMany(mappedBy="class1", cascade=javax.persistence.CascadeType.ALL)
   public java.util.Set<Class2> getClasses() {
      return this.classes;
   }

   public void setClasses(java.util.Set<Class2> classes) {
      this.classes= classes;
   }   




Class 2:

Code:
@javax.persistence.Entity
public class Class2 java.io.Serializable {

   private Long id;

   private Class1 class1;

   public Class2() {
   }   

   @javax.persistence.Id
   @javax.persistence.GeneratedValue
   public Long getId() {
      return this.id;
   }   

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

   @javax.persistence.ManyToOne
   public Class1 getClass1() {
      return this.class1;
   }

   public void setClass1(Class1 class1) {
      this.class1 = class1;
   }
}


Now, the test code:

Code:
// Create objects
Class2 c1 = new Class2();
Class2 c2 = new Class2();
Class2 c3 = new Class2();

Class1 in = new Class1();

// Add values
Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c1); list.add(c2); list.add(c3);

in.setClasses(list);

// Try to save it
in = hib.merge(in);

// I now want to iterate through list of classes (Class2) in [b]in[/b] object
Iterator<Class2> iter = in.getClasses().iterator();

iter.next(); <- HERE I GET java.util.ConcurrentModificationException !!!



What is the problem here ?! Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 9:05 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
MilanMilanovich wrote:
Now, the test code:

Code:
// Create objects
Class2 c1 = new Class2();
Class2 c2 = new Class2();
Class2 c3 = new Class2();

Class1 in = new Class1();

// Add values
Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c1); list.add(c2); list.add(c3);

in.setClasses(list);

// Try to save it
in = hib.merge(in);

// I now want to iterate through list of classes (Class2) in [b]in[/b] object
Iterator<Class2> iter = in.getClasses().iterator();

iter.next(); <- HERE I GET java.util.ConcurrentModificationException !!!



Hi,
I think your problem is that you doing the iteration in the middle of a transaction. Hibernate does some things behind the scene when you invoke merge(). After calling merge you should let Hibernate do the commit (flush the objects to the database). After that you can iterate over the list.

Carlo
-----------------------------
please give me credits if this post helped you.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 31, 2008 12:58 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
carlolf wrote:
MilanMilanovich wrote:
Now, the test code:

Code:
// Create objects
Class2 c1 = new Class2();
Class2 c2 = new Class2();
Class2 c3 = new Class2();

Class1 in = new Class1();

// Add values
Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c1); list.add(c2); list.add(c3);

in.setClasses(list);

// Try to save it
in = hib.merge(in);

// I now want to iterate through list of classes (Class2) in [b]in[/b] object
Iterator<Class2> iter = in.getClasses().iterator();

iter.next(); <- HERE I GET java.util.ConcurrentModificationException !!!



Hi,
I think your problem is that you doing the iteration in the middle of a transaction. Hibernate does some things behind the scene when you invoke merge(). After calling merge you should let Hibernate do the commit (flush the objects to the database). After that you can iterate over the list.

Carlo
-----------------------------
please give me credits if this post helped you.


Dear Carlo,

no, actuall I'm not in a middle of transaction. I load object, iterate through its list, and change it, and later I will open transaction for saving. Actually, I saw that
Code:
iter.next();

the first time returns good, but when I call it the second time in some loop, it generates this exception:

Code:
java.util.ConcurrentModificationException
   at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(Unknown Source)
   at java.util.LinkedHashMap$KeyIterator.next(Unknown Source)
   at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
   ...


?!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next

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.