-->
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.  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How to flush only selected objects in session?
PostPosted: Tue Feb 12, 2008 7:54 pm 
Newbie

Joined: Tue Feb 12, 2008 5:34 pm
Posts: 4
We are using the "Session-per-conversation" pattern in a web application, with the application tier handling the starting and ending of a conversation, But we also have the requirement where during the conversation, we have to save only some of the session objects (not every thing in the session). The below example is a toned down version of what is happening in the application tier with openSession and session.close marking the conversation boundary, and every line in the rest of the code being a separate web Request.


Code:
// Open the session [start of conversation in the application]
Session session = sessionFactory.openSession();

// load a instance of A
A objA = session.get(A.class, "id_1");

// Update object objA
objA.setDescription("xyz");

// load a instance of B
B objB = session.get(B.class, "id_2");

// Update object objB
objB.setName("abc");

// Calling update on object objB only.
session.update(objB);

// If some condition met based on some sytem rules
if (some condition met) {
     session.update(objA);
}

// Close the session [end of conversation in the application]
session.close();


When i close the session, with flush mode auto, it flushes the session. During the flush, it issues update statements for objB (which is as expected) and also update statements for objA (which is not intended/needed by the application tier).

Is there any way to tell hibernate just to issue flush statements for objB alone in the above example without detaching objA from the session?


Top
 Profile  
 
 Post subject: Re: How to flush only selected objects in session?
PostPosted: Tue Feb 12, 2008 11:34 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
You could evict the objects whose changes are not mean to be sent to database.


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 9:30 pm 
Newbie

Joined: Tue Feb 12, 2008 5:34 pm
Posts: 4
I have couple of reasons why i can't do that -
1) evict would detach the object from the session, and I still would like to have the object attached to the session as the subsequent calls might still need it.
2) My understanding is that evict would only detach associations that have cascade="evict" or higher I think. and would not evict cascade="none". That could potentially cause more issues in the application tier.
3) This also would mean that the application tier would have to know what it needs to detach (or evict) from the session and again reattch them. So far the application tier is kept agnostic of session and the conversation is achieved through interceptors in webwork. The only change we had when switching to "session-per-conversation" pattern is to say when to start and end a conversation and would not like to change that pattern.

So i think the better solution for my application would be to say what it wants to persits to database( i.e., objects that we want to issue the flush) from a bunch of obejcts that are associated to the sesion. But the question still is How can I do it?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 9:48 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
1- That would be the responsibility of L2 cache.
2- Change none to evict. That's not really a big change.
3- Someone has to make this decision, either way. It doesn't make much difference if you evict objects or select objects to be persisted. These two approaches have the same nature.

However, if you really know which objects have to make it to db you could evict all objects at the end of the conversation and merge the ones you want to send to db. If you know what Classes, vs Objects, you need to persist then you could have multiple session objects, one handling the read only or mock modification and the other one is the one being flushed to database. At the same time you should consider some read actions in hibernate might cause a flush to database. Then your logic really needs to have some knowledge of how HB works. One other thing you could do is to look into interceptors. Hibernate actually hands you a list of objects that are going to be flushed and in general it has a good set of call back functions. Unforunately I am not very experienced with interceptors so I prefer to say less about them.

Let me know what you think or if you could find a solution

Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 2:17 am 
Newbie

Joined: Tue Feb 12, 2008 5:34 pm
Posts: 4
farzad wrote:
.... It doesn't make much difference if you evict objects or select objects to be persisted. These two approaches have the same nature.

Well actually it does matter. In our web application, there are lot of entites that are getting loaded [or assocaited with the session] depending on what is needed on the client. It would be hard for the client side developer to identify what to evict. On the other hand, it is easy for him to say Save/update/delete this object based on the ui actions (and is a simple call to a Manager API).

farzad wrote:
.... if you really know which objects have to make it to db you could evict all objects at the end of the conversation and merge the ones you want to send to db

The problem here is we are in the middle of the conversation and therefore will not be able to evict all the objects in session. Well have to try out a solution where i get hold of all the obejcts in session[just don't know how yet], clear the session, reattach only the one that needs to be persisted, issue the flush, and then reattach all the objects back.

farzad wrote:
...you should consider some read actions in hibernate might cause a flush to database

Using session-per-conversation pattern and setting the Flush mode to Manual.

Using a second session solution is interesting and will try out, hard to guess on how hibernate would behave when trying to update a object in a new session when the original session is still open [ i would cross my fingers on this].

Just to rephrase the the original question i had, may be i can have a clean solution if,
when i issue a session.save(obj) or session.update(obj) ... or any such operation, can we let hibernate know to flush only those entities instead of all the objects in the session?
If not possible, would be very curious to know why it wouldn't be able to do that [kind of hard to think of a reason]?

Thanks a lot for replying.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 25, 2008 2:13 pm 
Newbie

Joined: Tue Aug 24, 2004 3:41 am
Posts: 4
Up !

Hi all,

I have the same problem and I would like to know if there is a solution to make Hibernate work this way.

For the same reasons, I don't want to use evict because it seems really inappropriate in my situation. It would be really complicated to evict and reattach objects to the session.

In fact, I just want Hibernate to flush specific objects. The ones I explicitly pass to save or update method.

Is there a way to do that ?

Thanks in advance for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 25, 2008 9:18 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
djoukit wrote:
Is there a way to do that ?



Get a new session and save the objects you like to save. Set the other session's flush mode to manual and never flush it.



Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 26, 2008 4:14 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Quote:
I have the same problem and I would like to know if there is a solution to make Hibernate work this way.

May I ask why you are needing this, or why is it a problem? Is it a performance consideration?

thanks


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 26, 2008 7:22 am 
Newbie

Joined: Tue Aug 24, 2004 3:41 am
Posts: 4
Thanks for your answers.

I may not use Hibernate correctly.

In fact, I use FlushMode.MANUAL and I call the flush method explicitly after the save, update or delete methods. Because I used to be in FlushMode.AUTO but the calls of the flush method were unpredictable which causes me some troubles.

The problem is that I have to load a lot of objects in my session, and when I explicitly save an object I don't want the whole session to be flushed.

I'd like to flush only the specific object I passed to the save method. Because at this point, some objects in my session are not in a correct state to be synchronized with the database.

I tried to play with the evict method but I get too many LazyInitializationException.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 26, 2008 8:43 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Hibernate's purpose is to save you from this sort of headache, are you sure you can't change your design? You could either:
    A)wait for all objects be ready to be synchronized with DB and then flush?
    B)load only the object to change, change it, flush
    C)review your logic so that it doesn't matter when hibernate chooses to flush


I wonder how it is possible you are going through "intermediate steps" you don't want to store; anyway if you have to mess a lot with flush/evict and lazy maybe you should avoid hibernate.
I would (personal opinion) go for C), so to delegate the DB logic to hibernate, which I trust more than my own capacity to oversee all database-related code.

Maybe you should trust it more and give it another try at the opposite way, delegating all responsibility to hibernate: the more you force him to do stuff, the more problems you get: standard patterns are long proven successfully.

Sanne


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 26, 2008 9:30 am 
Newbie

Joined: Tue Aug 24, 2004 3:41 am
Posts: 4
Thank you very much four your help Sanne.
I'll try to go for the solution C, and find a new way to work with Hibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 26, 2008 10:26 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Nice to hear that, I bet you'll like the result!


Top
 Profile  
 
 Post subject: Re: How to flush only selected objects in session?
PostPosted: Wed May 27, 2009 2:42 am 
Newbie

Joined: Tue May 26, 2009 5:35 am
Posts: 7
I have the same need, but my concern is different.

When using the session per conversation pattern you inevitably fill the session with many objects across the conversation (e.g. objects that displays in combo boxes). At the flush time, these objects and their corresponding lazy/non-lazy collections are LOADED for dirty checking. That means lots of SELECTs and lots of never used objects loaded into memory just for dirty checking.


Top
 Profile  
 
 Post subject: Re: How to flush only selected objects in session?
PostPosted: Wed May 27, 2009 5:01 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
I might be wrong but I think that's not the normal behaviour. You might be triggering this by having equals and hashCode implementations needing to load additional data.
Writing a correct equals/hasCode implementation is tricky and you can find lots of discussions about the topic.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: How to flush only selected objects in session?
PostPosted: Wed May 27, 2009 7:56 am 
Newbie

Joined: Tue May 26, 2009 5:35 am
Posts: 7
Indeed, this is not the normal behavior. I set up a small test for the scenario that didn't load anything more than needed.

But what else can it be wrong? I don't override any equals and hashcode, because I use the session per conversation pattern.

My environment: Hibernate 3.2.4.sp1 with JPA, JSF and Seam. I only use persistent or transient objects.

Have anyone seen such a problem?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 20 posts ]  Go to page 1, 2  Next

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.