-->
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.  [ 6 posts ] 
Author Message
 Post subject: Is it possible to list all dirty objects in a session?
PostPosted: Mon Jan 10, 2005 10:05 pm 
Newbie

Joined: Wed Sep 29, 2004 1:17 am
Posts: 6
Location: Auckland, New Zealand
Is it possible to query the second level cache for a list of all objects updated (including inserts and deletes) which have not yet been committed?

We're using optimistic locking (3.0 beta 1), and in some cases we know there will be a clash. Rather than just doing a...

Code:
    transaction.rollback();


... or similar, we'd like to get a list of objects which have been updated, and then - in certain cases - apply some logic which looks like this:

Code:
    session.evict( oldVersion );
    session.save( newVersion );


We know we can safely do this in some cases, and it would save our users a lot of headaches if we can get it working. Any suggestions on how this might be achieved?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 11, 2005 6:21 am 
Newbie

Joined: Fri Feb 27, 2004 6:49 pm
Posts: 18
Location: Paris, France
From what I understood, you in fact want to know the objects in level 1 cache.

At one time I was wanting to print all objects in the cache and I did something dirty to do so. It's absolutly dependent of hibernate implementation. Hibernate doesn't allow to be the cache contain in a clean way. So I did that:
Code:
   public void printHibernateEntities(RootContext ctx) throws Exception {     
      SessionImpl s = (SessionImpl) ctx.getFlowContext().getFlowManager().getHibSession();
      Map entities = (Map) getField(s, "entityEntries");
      List result = new ArrayList(entities.size());
      for(Iterator it = entities.values().iterator(); it.hasNext();) {
         Object o = it.next();
         String className = (String) getField(o, "className");
         Long id = (Long) getField(o, "id");
         result.add(className + ": " + id);
      }
     
      Collections.sort(result);
     
      for(Iterator it = result.iterator(); it.hasNext();) {
         System.out.println(it.next());         
      }
     
   }
   
   private Object getField(Object instance, String name) throws Exception {
      Field f = instance.getClass().getDeclaredField(name);
      f.setAccessible(true);     
      return f.get(instance);
   }

You can do the same kind of thing to solve your issue. However, I'm not sure I should tell you that since I'm pretty sure there is a much prettier solution to your problem.


Top
 Profile  
 
 Post subject: Looks pretty enough for me...
PostPosted: Tue Jan 11, 2005 4:18 pm 
Newbie

Joined: Wed Sep 29, 2004 1:17 am
Posts: 6
Location: Auckland, New Zealand
Thanks Henri,

Quote:
From what I understood, you in fact want to know the objects in level 1 cache.


Yes, that's exactly what I'm after. I couldn't see anything in the 'public' interface (i.e. in the hibernate.org package) which did this.

I understand that it might not be version resilient, since it relies on the implementation classes, but it should be good enough for now.

Perhaps we could get a function like this put in the public interface? (perhaps session.getDirtyObjectSet()??) Comments... expressions of interest welcome...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 12, 2005 7:07 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
can interceptors help?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 13, 2005 11:03 pm 
Newbie

Joined: Wed Sep 29, 2004 1:17 am
Posts: 6
Location: Auckland, New Zealand
Yeah, thanks Emmanuel, that's what I'm looking for.

The only thing I'm not sure on is how to determine which objects are dirty.

I thought this would be obvious from , but that doesn't always seem to be called. For example in the following scenario, the Cat (momo) has a reference to its Vet (sarah). If you save the Cat first, onFlushDirty() is never called on the Vet.

Is this the expected behaviour? Is there some other way to determine which objects are dirty?

Code:
    sarah = Vet.create( "sarah", null );
    momo = Cat.create( "momo", 'm', 8.5F, sarah );
    // i.e. momo.setVet( sarah );
    session.save( momo );

Quote:
onSave( [Cat 'momo'])
isTransient called on [Vet 'sarah']


Code:
    session.save( sarah );

Quote:
onSave( [Vet 'sarah'])


Code:
    session.flush();

Quote:
preFlush( [ [Cat 'momo'], [Vet 'sarah'] ] )
findDirty( [Cat 'momo'] )
onFlushDirty( [Cat 'momo'])
findDirty( [Vet 'sarah'] )
Hibernate: insert into CAT (version, NAME, sex, weight, vet, CAT_ID) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into VET (version, NAME, certificationDate, VET_ID) values (?, ?, ?, ?)
Hibernate: update CAT set version=?, NAME=?, sex=?, weight=?, vet=? where CAT_ID=? and version=?
postFlush()


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 13, 2005 11:06 pm 
Newbie

Joined: Wed Sep 29, 2004 1:17 am
Posts: 6
Location: Auckland, New Zealand
Quote:
I thought this would be obvious from , but that doesn't always seem to be called.


Correction, I meant to say:
Quote:
I thought this would be obvious from onFlushDirty(), but that doesn't always seem to be called.


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