-->
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: StackOverflowException when using onDelete event
PostPosted: Thu Jul 26, 2007 5:24 pm 
Newbie

Joined: Fri Sep 15, 2006 2:09 am
Posts: 11
Hi.

I've got a problem with the hibernate Event system. The following constellation mapping:

A->B->C

All mappings are implemented as sets with all-delete-orphan cascades.
Deleting A deletes all objects related to A (B+C).

Now I have an additional mapping D this references the object C with a many-to-one mapping no cascades. No mapping is done from C to D. So C knows nothing about D. If I create a record for D, referencing C, I can't delete A, B or C anymore because of the foreign key constraint. Hibernate won't remove D automatically - I have to live with that and I would have to delete D first manually before deleting A.

Now the Events come to rescue. In this I check in onDelete if it's an instance of C and execute a delete on table D with the id of C. Here comes the problem. If I delete A i have no problem - everything works and my onDelete is called. But If I delete C directly, I get an StackOverflowException, because when I delete records in D, the onDelete is called AGAIN for object C in an endless loop. I don't know why this happens. Here's the onDelete implementation:

Code:
public class VoDeleteListener extends DefaultDeleteEventListener implements DeleteEventListener {

   public void onDelete(DeleteEvent pEvent) throws HibernateException {
      
      clearActions(pEvent);
      
      super.onDelete(pEvent);
   }

   public void onDelete(DeleteEvent pEvent, Set pArg1)
         throws HibernateException {   

      clearActions(pEvent);      
      
      super.onDelete(pEvent, pArg1);
   }
   
   private void clearActions(DeleteEvent pEvent) {
            
      if (pEvent != null) {
         
         if (pEvent.getObject() instanceof Foo) {
            
            Foo lFoo = (Foo) pEvent.getObject();
      
            String lHQL = "delete from sometable where foo = :foo";
               
            Query lQuery = pEvent.getSession().createQuery(lHQL);
            lQuery.setParameter("foo",lFoo);
            lQuery.executeUpdate();
         }
      }
   }
}


Why does a deletion of D (lQuery.executeUpdate();) trigger the onDelete of C again, and again, and again?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 5:28 am 
Newbie

Joined: Fri Jul 27, 2007 4:39 am
Posts: 7
Hi vguna,

The problem is that the call to executeUpdate() triggers a delete and your class is written to catch delete events. I had a similar issue (handling inserts and updates) and I could not find any documentation.

I found a solution though by having a look at the default implementation in DefaultDeleteEventListener, the class you are extending. It is not easy to follow, but try this as long as nobody else answers to your post with a better idea.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 8:29 am 
Newbie

Joined: Fri Sep 15, 2006 2:09 am
Posts: 11
user_who_lost_his_account wrote:

The problem is that the call to executeUpdate() triggers a delete and your class is written to catch delete events. I had a similar issue (handling inserts and updates) and I could not find any documentation.


Yes, I know, but why? Since I delete another class (D) different from the one the onDelete is called on (C) - so why is onDelete called AGAIN for C? I could understand that the method is invoked for D then. But event.getObject is instanceof class C when my onDelete is called?!

Yes, you're right. Documentation is really poor on this point :(. And no code examples on google. Seems that only few people take this approach.


Quote:
I found a solution though by having a look at the default implementation in DefaultDeleteEventListener, the class you are extending. It is not easy to follow, but try this as long as nobody else answers to your post with a better idea.


My workaround is to set an attribute on the object C to mark this as "D already deleted" flag. Not nice but works.

So perhaps any of the hibernate guru's have an answer to it...


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.