-->
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: Only commit certain dirty objects
PostPosted: Thu Jul 29, 2004 12:55 am 
Senior
Senior

Joined: Sat Jul 17, 2004 5:16 pm
Posts: 143
I would like to update only certain objects in my object graph, and include dirty-checking.

e.g.

SessionStart

Read objA, objB, objC from DB

...

Change objB and objC in Java

...

//I know I want to update objA and objC only

Hibernate will update only objC //since objA is not dirty

Commit //and objB is not changed in DB

The first thing that I think of is starting a new session, and passing the objects I want to commit to it. But this would eliminate the dirty checking... Is something like this possible?

Thanks,
Chris


Top
 Profile  
 
 Post subject: RE: Only commit certain dirty objects
PostPosted: Thu Jul 29, 2004 4:44 pm 
Regular
Regular

Joined: Tue Jun 22, 2004 8:01 pm
Posts: 106
Location: PowderTown, Utah, USA
So, if I understand you corrently, you want to selectively write changes to a few of the persistent objects, not to all of them? (Not sure why you'd need this but, here goes!)

Objects in Hibernate can exist in three pseudo-states (these are MY terms, not necessarily the Hibernate team's terms... it's just how I like to think of things!):

Transient - New objects that have never been persistent
Attached (Persistent) - Objects under hibernate management that are associated with a session
Detached - Objects that used to be under management but now are not (serialized across the wire or the Session has been closed).

What it sounds like you want to do is make updates to some of your objects, but not all. I can think of a couple ways to pull this off.

1) Assuming your operation can make use of multiple sesions, you can load the objects in one session and then end the session, which will detach your objects. Obtain a new session and selectively attach ONLY the objects you want to change. In your example, you'd only attach ObjC, not the other two. To attach an object, use Session.Update() or Session.Lock(ObjC, LockMode.READ). FYI, Session.Update does not actually force a SQL Write... it's more like "Update the persistent state of the object." It's almost "attach." Lots of folks think you have to call "Update" to save changes to attached objects in the database. You don't. It happens automatically when your session is "Flushed" by closing or a transaction commit.

2) If you're using one single session (for example a ThreadLocal or OpenSessionInView for a Web app) then there's a few easy ways to do it. The easiest way I can think of is to clone the objects you want to change, then update the clones. Then you can possibly re-attach the object to the session for updating. I haven't tested this but here's what you might do:
... Obtain Session
ClassA objA = (ClassA)session.load(ClassA, idA);
ClassB objB = (ClassB)session.load(ClassB, idB);

ClassA cloneA = objA.clone();
ClassB cloneB = objB.clone();

... Modify cloneA and cloneB ...

// now save the clone using the special saveOrUpdateCopy
objA = session.saveOrUpdateCopy(cloneA); // pretty sure this will work

Instead of saveOrUpdateCopy() you might try to session.lock(cloneA, LockMode.READ) but I think it will throw an exception since only one instance of a persistent object can be in the session at once. Dunno. Try it.

Go read the docs on saveOrUpdateCopy to see why I think that will work well with a clone. Here's the link:
http://www.hibernate.org/hib_docs/api/n ... ang.Object)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 29, 2004 6:49 pm 
Beginner
Beginner

Joined: Wed Jul 21, 2004 12:28 pm
Posts: 27
Location: New York
in case of objectB - there is nothing to it just evict it from the session so it will not be updated. You can reassociate it later if you need to

in case of objectA you have to let hibernate somehow to know that the object is dirty. One easy way of doing it would be to introduce custom interceptor.

Alex.

_________________
Thanks,
Alex


Top
 Profile  
 
 Post subject: Re: RE: Only commit certain dirty objects
PostPosted: Thu Jul 29, 2004 9:50 pm 
Senior
Senior

Joined: Sat Jul 17, 2004 5:16 pm
Posts: 143
I am exploring how to integrate Hibernate into our web framework, and see if there is a way to use Hibernate's dirty checking and lazy loading (which it looks like wont work for us). The thing I am going for is keeping a session open indefinitely (so a user could go through screen workflows, without hitting commit on them, and then on the one where the user hits commit, thats the only one with objects to commit, and we dont want to rely on opening a session at the beginning of each workflow).

cardsharp wrote:
Objects in Hibernate can exist in three pseudo-states ...


Right, in my example, I am talking about all "attached" objects

cardsharp wrote:
1) Assuming your operation can make use of multiple sesions, you can load the objects in one session and then end the session, which will detach your objects.


In this case you would not have dirty checking, so all fields of all objects will be persisted even if they werent changed (at least from my tests this is what I see)

cardsharp wrote:
2)
// now save the clone using the special saveOrUpdateCopy
objA = session.saveOrUpdateCopy(cloneA); // pretty sure this will work


This is an interesting method, I had not noticed it. I think in this case if you attach it to a different session, there is no dirty checking, if you attach it to the same session, a commit will commit all dirty objects, not only the ones I would like to


Quote:
in case of objectB - there is nothing to it just evict it from the session so it will not be updated. You can reassociate it later if you need to


Right, I somehow want to evict all objects except the ones I pass to a method. Maybe I could walk the object graph and do that myself...

Quote:
in case of objectA you have to let hibernate somehow to know that the object is dirty. One easy way of doing it would be to introduce custom interceptor.


Hmm, it would be nice to use the auto-dirty checking though this sounds like an option

Thanks to all! I think we will change gears and go back to opening a session and transactions, doing some queries, then closing the session. Then to commit, open another session, reattach, and commit and close the session there. Therefore there is no dirty checking or lazy loading while the session is not open. Thanks, Chris


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.