-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: handling sessions question
PostPosted: Sat Feb 02, 2008 6:09 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
Hi,
I am having trouble to figure out what is the right thing to do.
This is my case:
I am creating an object with 1 session and saving it into the db.
I am holding it somewhere in the application too, and then later in the time, other session updates it (it got versioning and everything is good)
But the the first session, the one that saved the object before, fails with this kind of exception:
Code:
org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
   at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
   at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)


I understand that it somehow detects that the object it updated before was changed and tries to flush it, even though i not asked it for, because i already did it in other session. (the actual action that this session does is completely different, but i guess the old object is in its cache...)

The question is what is the right thing to do here, i dont think it is wise to use only 1 session in the application to avoid that...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 6:54 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Hi,

After you end the first session, your entity becomes "detached". This means it's not being managed by hibernate any more.

To re-attach in your second session, use session.merge(yourStaleObject).

-Paul


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 6:59 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
This happens to me when the first session is not yet ended, it is still running, just not touching this object that the second session is using.

so if i should use merge for detached object, when should i use saveOrUpdate().

seems i just should replace saveOrUpdate i was using with merge...
(except for the new objects case ofc)

should i do save for new and merge always for other objects?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 7:02 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Oh, sorry I misread assuming the problem was in the second session. Can you post the code that manages the session, transaction and object state please?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 7:22 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
well i am not sure i am doing it well
but i made some class, named DataProvider
that in its ctor i did:

Code:
this.session = HibernateUtil.reserveSession();
this.transaction = this.session.beginTransaction();

and its is holding the session and the transaction all along.

then i implemented methods in it:
commit:
Code:
this.transaction.commit();
this.transaction = this.session.beginTransaction();


rollback:
Code:
this.transaction.rollback();


release:
Code:
HibernateUtil.releaseSession(this.session)


it got there some events and notification handling,
and some specific actions i need in my app, like save object, create new object, query stuff

so what i do in my app is create DataProvider and use it to save objects,
then i commit() or rollback() at the end.
sometimes i commit and keep working with the same DataProvider
untill i call the release() method.

the hibernateUtil:
Code:
reserveSession - sessionFactory.openSession()
releaseSession - session.close();


does this handling seems ok for you?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 7:36 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Ok it looks like DataProvider is a wrapper for a hibernate session. I guess there's no harm in that.

I can't see anything wrong with what you have posted, as long as you are calling the right methods in the right order. Are you sure that the 1st session is being released at the correct time? I.e. before the second session does any work?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 7:43 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
no no no

thats the point. first session is not released.

they both operate simultaneously.

i have 2 DataProviders in 2 different threads.

the first session keeps running while the second is used...

but the 2 cases are independent, i cant see how i can synchronize the things...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:09 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
is this not a normal setting, what i have here?
should i be using only 1 session all along... or maybe i need somehow to synchronize objects between sessions all the time?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:13 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Ok now I understand, sorry I'm having a slow morning! =)

In my experiance, it makes sense for each session to get it's own handle on any entities it needs to work on. In your case, you are sharing instances between threads and I'm pretty sure that is what's causing your exception.

A reasonable solution could be to only share the entity identifier between threads, and have each perform a session.load(...) to get a handle on their own version of the entity object. If you have configured a second level cache then performance will still be decent.

By the way - I'm no expert. There may be a better way of doing this! I would test this idea to prove it works, but there could well be a better way of implementing shared entity instances.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:23 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
Thanks for you help. I am having a morning here also. :)

I understand what you are saying, but seems to me that it will cause more memory waste - each object will load in several sessions.

It is much cleaner and easier for me to deal with objects in the application, rather than passing ids.

I guess i will have to merge my object from the first session into the second session in my case so it will work?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:33 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
I don't think my merge() suggestion helps, now that I understand your requirement.

As far as i see it, there are two options:

1) Use the id/cache mechanism I suggested
2) Share the session between threads (i'm not sure this is a good idea, but you could experiment with it)

PS - I understand your concern regarding memory waste, but if you think about hibernate in web applications, that's basically the same as what you are trying to do. i.e session per thread, each thread looks up it's own objects.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:37 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
when i come to think of it, i dont understand how the id thingy will work.

my problem happens back in the first session, when it automatically tries to flush object updated in the second session.
at the time of the auto flush the first session does not try to update the problematic object, it updates some other object.

so if i share ids, it will still try to autoflush this object...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:40 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
Archmisha wrote:
when i come to think of it, i dont understand how the id thingy will work.

my problem happens back in the first session, when it automatically tries to flush object updated in the second session.
at the time of the auto flush the first session does not try to update the problematic object, it updates some other object.

so if i share ids, it will still try to autoflush this object...


Yes but if each session fetches it's own data, they will each have their own instance. I would not expect the first session to throw an exception in this scenario.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 8:49 am 
Beginner
Beginner

Joined: Thu Aug 09, 2007 3:48 pm
Posts: 38
Hmm if session1 loads an instance, then session2 does saveOrUpdate on it, isnt now each session got each own insatnce of the object?
saveOrUpdate associates the object to the second session


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 02, 2008 9:03 am 
Regular
Regular

Joined: Mon Aug 20, 2007 6:47 am
Posts: 74
Location: UK
if session1 executes load(MyEntity.class,id)

and session2 executes load(MyEntity.class, theSameId)

then although each session has the same entity, they are not the same instance.


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