-->
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 associated instances from within interceptor
PostPosted: Fri Jun 13, 2008 10:35 am 
Newbie

Joined: Thu Dec 21, 2006 7:30 am
Posts: 11
Hibernate version:3.1.3

Hi -
I have a little trouble with persisting objects.

I have an interceptor in which I want, based on the state of the object passed in onFlushDirty, to change the state of an associated object.

Code:
public void onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyName, Type[] type, SecurityUser secUser) throws CallbackException
   {
      // Change variable
      boolean changed = false;
      // Surgery
      if(entity instanceof Surgery)
      {
         Surgery surgery = (Surgery) entity;
         // Extract values
         String oldState = null, newState = null;
         int state = -1;
         SurgeryRoom surgeryRoom = null;
         for(int i = 0; i < currentState.length; i++)
         {
            String property = propertyName[i];
            // State
            if(property == "state")
            {
               oldState = (String) previousState[i];
               newState = (String) currentState[i];
               state = i;
               continue;
            }
                                // Surgery
            else if(property == "surgeryRoom")
            {
               surgeryRoom = (SurgeryRoom) previousState[i];
            }
         }
         // Checking changes in state
         if(!newState.equals(oldState))
         {
            if(newState.equals("Ongoing"))
            {
               logger.info("starting Surgery " + surgery.getId());
               if(surgeryRoom != null)
               {
                  if(surgeryRoom.getOngoingSurgery() != null)
                  {
                     if(surgeryRoom.getOngoingSurgery() != surgery)
                     {
                        throw new CallbackException("Cannot start Surgery:[Id=" + id + "] because there is an ongoing Surgery:[Id=" + surgeryRoom.getOngoingSurgery().getId()+"] in SurgeryRoom:[Id=" + surgeryRoom.getId() + "]!");
                     }
                  }
                  else
                  {
                     surgeryRoom.setOngoingSurgery(surgery);
                  }
               }               
               changed = true;
            }
            else if(newState.equals("NotBegun"))
            {
               logger.info("aborting Surgery " + surgery.getId());
               if(surgeryRoom != null)
               {
                  if(surgeryRoom.getOngoingSurgery() != null)
                  {
                     if(surgeryRoom.getOngoingSurgery().getId() == surgery.getId())
                     {
                        surgeryRoom.setOngoingSurgery(null);
                     }
                  }
               }
               changed = true;
            }
            else if(newState.equals("Finished"))
            {
               logger.info("finishing Surgery " + surgery.getId());
               if(surgeryRoom != null)
               {
                  if(surgeryRoom.getOngoingSurgery() != null)
                  {
                     // We have to check on id as we are dealing with copies.
                     if(surgeryRoom.getOngoingSurgery().getId() == surgery.getId())
                     {
                        surgeryRoom.setOngoingSurgery(null);
                     }
                  }
               }
               changed = true;
            }
            else if(newState.equals("Cancelled"))
            {
               logger.info("cancelling Surgery " + surgery.getId());
               if(surgeryRoom != null)
               {
                  if(surgeryRoom.getOngoingSurgery() != null)
                  {
                     if(surgeryRoom.getOngoingSurgery().getId() == surgery.getId())
                     {
                        surgeryRoom.setOngoingSurgery(null);
                     }
                  }
               }
            }
         }
      }
      return changed;
   }


However sometime the SurgeryRoom object get persisted and sometimes not.
I know that persisting of objects is managed by findDirty. Is there any possibility for me to mark the SurgeryRoom object dirty and force a onFlushDirty on it?

Perhaps my approach is wrong altogether and I should have chosen a different strategy?

Any help is appreciated.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 13, 2008 1:41 pm 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
Hi jonigkeit,

I think that your "approach is wrong altogether". What you are doing in this method is typical business logic and this should be done elsewhere - before you commit the transaction.

The Hibernate interceptor may be used as a vetoer or get some meta information about a working set being committed - but it should not do (or correct) the business logic.

_________________
Carlo
-----------------------------------------------------------
please don't forget to rate if this post helped you


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 13, 2008 3:27 pm 
Newbie

Joined: Thu Dec 21, 2006 7:30 am
Posts: 11
Thanks for replying Carlo.

I thought so myself. I should have chosen a different approach. Unfortuneatly the current system is quite complex (2 years of development) so it is going to be a tough one to change.

If have however found a work around using hql updates.

For instance the "Ongoing" case can be solved using the following code:
Code:
if(surgeryRoom.getOngoingSurgery() != null)
{
   if(surgeryRoom.getOngoingSurgery().getId() != surgery.getId())
   {
      ProductionLogger.INTERNAL.warn("Finishing Surgery:[Id=" + surgeryRoom.getOngoingSurgery().getId() +
         "] which is ongoing in SurgeryRoom:[Id=" + surgeryRoom.getId() + "] since Surgery:[Id=" + surgery.getId() +
         ",SurgeryRoomId=" + surgeryRoom.getId() + "] was started.");
      String hql = "UPDATE " + Surgery.class.getName() + " set state = 'Finished', stop = :stop WHERE id = :surgeryId";
      session.createQuery(hql).setLong("surgeryId", surgery.getId()).setDate("stop", new Date()).executeUpdate();
      hql = "UPDATE " + SurgeryRoom.class.getName() + " set ongoingSurgery = :surgeryId WHERE id = :surgeryRoomId";
      session.createQuery(hql).setLong("surgeryId", surgery.getId()).setLong("surgeryRoomId", surgeryRoom.getId()).executeUpdate();
   }
}


But it is an ugly hack as it causes the locked entities to be evicted from the session cache.

I guess there is no way around the big refactor task.


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.