-->
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.  [ 13 posts ] 
Author Message
 Post subject: moving objects to another session
PostPosted: Fri May 20, 2005 8:07 am 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
Hello,

Due to multiple threads, each one having its own hibernate session, we need to move objects to another session.

It doesn't seem to be possible however, I think because of a bug in Hibernate version 2.1.8.

What I do is simple (s1 and s2 are two open hibernate sessions):

1. Object obj = s1.get(someclass, someid);
2. s1.evict(obj); // or session1.clear()

in another thread:
3. s2.lock(obj, LockMode,NONE);


The s2.lock() results in:

net.sf.hibernate.LazyInitializationException: Illegally attempted to associate a proxy with two open Sessions
at net.sf.hibernate.proxy.LazyInitializer.setSession(LazyInitializer.java:152)
at net.sf.hibernate.impl.SessionImpl.reassociateProxy(SessionImpl.java:1027)
at net.sf.hibernate.impl.SessionImpl.unproxyAndReassociate(SessionImpl.java:1011)
at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1709)

Looking in LazyInitializer.setSession() I see:

if ( session!=null && session.isOpen() ) {
//TODO: perhaps this should be some other RuntimeException...
throw new LazyInitializationException("Illegally attempted to associate a proxy with two open Sessions");


Indeed s1 is still open and the session field of the evicted object is not cleared, even when it is detached from s1. However the text of the exception is not quite accurate, since formally the object after s1.evict() is no longer associated with the first session. Hibernate falsely assumes that as long as the session is open, the object is associated, as if no s1.evict() or s1.clear() had been taken place.

According to the "Hibernate in action" book on page 116 section 4.1.1 an object is detached by session close/clear/evict, no difference is made between these. Now it seems that this is not fully the case.

Should not the object(s) evicted/cleared from the session have their session field put to null?

As it is, we can only move an object into another session if the first session has been fully closed, but I don't understand the deeper reason for that.

Regards,

Peter


Top
 Profile  
 
 Post subject: Is my question too difficult or too stupid?
PostPosted: Fri May 20, 2005 12:49 pm 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
Hello,

I'm answering to my posting, which is the third rephrasing in an attempt to get any feedback or hint to my problem.

Now I'm starting to wonder: is my problem/question too difficult or is the question too stupid to merit any resonse? Please let me know at least that :).


Thanks in advance,

Peter


Top
 Profile  
 
 Post subject: Re: Is my question too difficult or too stupid?
PostPosted: Fri May 20, 2005 1:44 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
plm wrote:
Hello,

I'm answering to my posting, which is the third rephrasing in an attempt to get any feedback or hint to my problem.

Now I'm starting to wonder: is my problem/question too difficult or is the question too stupid to merit any resonse? Please let me know at least that :).


Thanks in advance,

Peter


I'm fairly new at Hibernate, so I don't have any answer, but I had a problem in my app where an object got passed to another thread that tried to update it and got that same exception. But when I evicted the object from the first session, I was able to attach it to the second session without any problems. Maybe nobody is responding because it works for them.

If you can get a bare-bones example with hbms and code that produces the problem, so that someone can try to reproduce it, that might help you get a response.


Top
 Profile  
 
 Post subject: Re: Is my question too difficult or too stupid?
PostPosted: Fri May 20, 2005 1:52 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
plm wrote:
Hello,

I'm answering to my posting, which is the third rephrasing in an attempt to get any feedback or hint to my problem.

Now I'm starting to wonder: is my problem/question too difficult or is the question too stupid to merit any resonse? Please let me know at least that :).


Thanks in advance,

Peter


Are you certain that all aggregate/collection objects have also been evicted from the first session ? There is a cascade='evict' option in v3


Top
 Profile  
 
 Post subject: Re: Is my question too difficult or too stupid?
PostPosted: Sat May 21, 2005 3:12 am 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
pksiv wrote:
Are you certain that all aggregate/collection objects have also been evicted from the first session ? There is a cascade='evict' option in v3


Yes, I should have mentioned that the same happens when we call s1.clear(), i.e. all objects have been evicted from the first session.

Also, looking inside the Hibernate code in LazyInitializer.setSession() it can be seen what Hibernate is doing: Any ex-persistent object, which apparently still have their session field set, is checked for if the session it once belonged to is still open. IMO this is wrong, it should be checked if it still belongs to the session. Whether that session is still open or not should not be relevant.


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 21, 2005 6:11 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
two things...

Your usecase *smells* bad I must say...two *threads* with their own session need to exchange objects...sounds like you should use more explicit session control instead. Why doesn't T2 just load the object T1 wants it to operate on ?

that said evict() should *probably* wipe out the session connection, create a jira issue for it.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 21, 2005 6:29 am 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
max wrote:
two things...

Your usecase *smells* bad I must say...two *threads* with their own session need to exchange objects...sounds like you should use more explicit session control instead. Why doesn't T2 just load the object T1 wants it to operate on ?

that said evict() should *probably* wipe out the session connection, create a jira issue for it.


Hello max,

I have just done so (create jira issue).

I think it is very normal in a multithreaded application to pass objects around. As for multithreaded batch applications it is normal to keep sessions open for a longer amount of time. When the objects being passed around are properly detached, i.e. made transient, then are reattached later somewhere else (whether in the same JVM or not should not play a role) I don't see why this should be a sign of bad design.

Of course it should always be clear which thread is responsible for managing the objects lifecycle. Therefore the sending thread is evicting objects before giving them to the worker threads.


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 21, 2005 6:53 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
as long as you are aware of where your transaction boundaries are and the possible inconsistency issues there is then yes its ok...but normally it smells.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: A temporary solution to your problem
PostPosted: Thu May 26, 2005 5:25 pm 
Newbie

Joined: Thu May 26, 2005 5:18 pm
Posts: 3
As I've been battling with the same problem as you all day, I have come up with a fix that seems to work fine.

Follow these steps.

1) Remove AbstractLazyInitializer.class from hibernate.jar

2) Create the packages in your source tree:
org.hibernate.proxy
org.hibernate.event.def

3) Get the source for AbstractLazyInitializer.java and add
"&& s != null" to if ( session!=null && session.isOpen()

4) Copy this file to the org.hibernate.proxy package

5) Create a new class called NewEvictEventListener in org.hibernate.event.def

6) Copy the contents of DefaultEvictEventListener (hibernate src) to this class

7) Add "li.setSession(null) ;" after the instantiation of the "li" (lazyinitializer) object

8) Your "Configuration" class needs to be loaded like this:
configuration = new Configuration();
configuration.setListener("evict", new NewEvictEventListener());

That's it.

Hope this was helpful.[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 27, 2005 1:55 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
thats a very wrong way of doing it ;)

please submit this as an issue to the jira (with testcase to show it), should be trivial to fix.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 27, 2005 6:06 am 
Newbie

Joined: Thu May 26, 2005 5:18 pm
Posts: 3
max wrote:
thats a very wrong way of doing it ;)

please submit this as an issue to the jira (with testcase to show it), should be trivial to fix.


Well, would you care to explain. Basically, here's an example for you

hibPersistentClass p1 = session1.load(hibPersistentclass.class, 1);
// p1 has lazy collections and is a proxy
session1.evict(p1);

session2.saveOrUpdate(p1);
// error !!!! illegal attempt to associate a proxy with two sessions,

Well, if you look at the objects more closely, the proxies have indeed been removed from session1, p1 is detached and the only thing that remains is the reference to the old session (which is still open)

Now, when you try to change sessions by reassociating, then Hibernate doesn't let you because the old session is still open.

Passing setSession(null) to it, in this case allows you to remove the old session and the new one will get assigned as soon as you attach it to a new session.

What's wrong with that?


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 27, 2005 6:15 am 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
max wrote:
thats a very wrong way of doing it ;)

please submit this as an issue to the jira (with testcase to show it), should be trivial to fix.


hello max, i have submitted an issue last saturday:

http://opensource.atlassian.com/project ... ge=history


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 27, 2005 6:24 am 
Newbie

Joined: Thu May 26, 2005 5:18 pm
Posts: 3
max wrote:
two things...

Your usecase *smells* bad I must say...two *threads* with their own session need to exchange objects...sounds like you should use more explicit session control instead. Why doesn't T2 just load the object T1 wants it to operate on ?

that said evict() should *probably* wipe out the session connection, create a jira issue for it.


The reason why I need separate threads is quite simple here.

GUI application, tree view which doesn't load it's items until the relevant node is accessed, so the session has to stay open in order for lazy to work... then when you implement an ActionListener on one of the tree nodes, it is executed in a separate thread, AWT-Event something ... now, I need to actually save the objects which were opened in the other session (and are being passed through), but it's obviously still open. So, I need to evict the objects from the old session temporarily in order to persist them. Now, the old session needs to keep working with the same object afterwards, so I reassociate it.

Is there really any other way of doing this if I need lazy?


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