-->
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.  [ 4 posts ] 
Author Message
 Post subject: Do detached objects need to be in context to be deleted?
PostPosted: Mon Feb 09, 2009 10:35 am 
Beginner
Beginner

Joined: Sat Feb 07, 2009 12:31 am
Posts: 21
Hibernate: 3.3.1.GA
Annotation 3.4.0.GA
EntityManager 3.4.0.GA

Hi,

I read some parts of the book titled "Java Persistence with Hibernate". It says:
Quote:
This means you don’t have to reattach (with update() or lock()) a detached instance to delete it from the database. In this case, the call to delete() does two things: It reattaches the object to the Session and then schedules the object for deletion, executed on tx.commit(). The state of the object after the delete() call is removed.


and he uses this code:

Code:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.delete(item);
tx.commit();
session.close();


But when I try the same thing (deleting a detached object) it gives me this exception:

Code:
Exception in thread "main" java.lang.IllegalArgumentException: Removing a detached instance com.samples.MyEntity#30
   at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventListener.java:47)
   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 com.samples.MyEntityHome(MyEntityHome.java:82)
   at com.samples.MyMain.main(Executor.java:70)


Now I'm really confused.

My code in deleting an object:

Code:
      Session s =
      ((HibernateEntityManager)
         DataSrc.getHibEntityMF().createEntityManager())
         .getSession();
      
      s.beginTransaction();
      
      s.delete(myEntityObj);
      
      s.getTransaction().commit();


I just want to confirm if what's written in the book is correct or not, if the detached object could be deleted without re-attaching it to a persistent context. And if it does requires re-attachment, what's the best way to do it, it's just doesn't look good if it's going to issue an insert statement before issuing a delete statement as what happens if you call merge() method.

For now, my solution is to load a persistent object by copying the id of detached object and use the persistent object to delete what my detached object is representing.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2009 5:08 am 
Regular
Regular

Joined: Thu Sep 06, 2007 2:22 am
Posts: 108
Location: Noida,India
Hi unrealdummy,

What you read in the book, is correct -
Quote:
This means you don’t have to reattach (with update() or lock()) a detached instance to delete it from the database. In this case, the call to delete() does two things: It reattaches the object to the Session and then schedules the object for deletion, executed on tx.commit(). The state of the object after the delete() call is removed.



This is correct if you use Hibernate Native for Peristence.
As you know Hibernate also implement (partially) JPA specification throw using
Quote:
Entity Manager
(that what you are using ), then it follow the JPA specification. If you go future in Same Chapter Of book ("JAVA Persistence with Hibernate") then it clearly tell you can't delete Detach object Directly through JPA implementor . you have to attach it with with Persistence Context.

And for the problem, as you mention

Quote:
For now, my solution is to load a persistent object by copying the id of detached object and use the persistent object to delete what my detached object is representing. .


you can use this alternative approach -
- Load the object in persistence context without hitting the database. Use
Code:
getReference()
API of EntityManager.
- Now you can call
Code:
remove()
API to remove it.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2009 10:38 am 
Beginner
Beginner

Joined: Sat Feb 07, 2009 12:31 am
Posts: 21
Hi parmendratyagi

Thanks for a quick response.

After reading that part of the book twice, I figured out what I was doing wrong.

I believe I am seriously misled by the exception's description:

Code:
Exception in thread "main" java.lang.IllegalArgumentException: Removing a detached instance com.samples.MyEntity#30
   at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventListener.java:47)
   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 com.samples.MyEntityHome(MyEntityHome.java:82)
   at com.samples.MyMain.main(Executor.java:70)


There's nothing wrong with deleting detach objects, what I was really doing before when that exception was thrown was, I was deleting a transient object, but the exception clearly states that I was trying to delete a "detached" object instead of saying I was trying to delete a "transient" object.

I tried deleting a detach objects and it was good. The difference between a transient and detached object wasn't clear to me until I read the book twice and tried experimenting with it.

So, I believe it's not really about whether I'm using a "JPA version" of hibernate or native hibernate.

Quote:
This is correct if you use Hibernate Native for Peristence.
As you know Hibernate also implement (partially) JPA specification throw using
Entity Manager


Though your response made me make experiment using native Hibernate and it turns out that it is OK to delete a transient object, so you made half of the point valid. There's a difference between JPA hibernate and native with regards to handling transient objects, but not with regards to detached objects.

I'm sorry I was just a bit confused, and really, the exception is very misleading, it must have said:

"Removing a transient instance com.samples.MyEntity#30"

instead of:

"Removing a detached instance com.samples.MyEntity#30"

when I was really using a transient instead of detached object.

So there's no way of directly deleting an object without that object going from a persistent state after all, ei? Because in the graph shown in the book, there's no transition from transient to detached state without taking a path to persistent state. The graph was even incomplete, it doesn't show a path from detached state to removed state.

I think we're done here, thanks anyways, please post a reply if you think I'm missing something or you want to add up something that could help me understand more about this matter.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2009 11:03 am 
Regular
Regular

Joined: Thu Sep 06, 2007 2:22 am
Posts: 108
Location: Noida,India
Hi unrealdummy,

Thanks for the sharing the information.

I thing, you were assigning value to the identifier property of transient object before calling delete on that object, only so Hibernate was detecting it as detached object.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.