-->
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.  [ 7 posts ] 
Author Message
 Post subject: Hibernate + AJAX + multiple requests
PostPosted: Mon Mar 02, 2009 12:45 am 
Newbie

Joined: Sun Mar 01, 2009 11:44 pm
Posts: 6
Hi,

I'll start by saying that I'm rather new to Hibernate but have read quite a bit in short period of time.

I apologize in advance for asking a question that has likely come up many times already, but unfortunately, I'm missing the keywords to search on.

My app has an AJAX front end. (I am not writing the frontend). When the user logs into the system, I fetch an 'account' object from the database and then store it in the HttpSession.

On future requests, I look up the 'account' from the HttpSession to perform more database lookups. My problem is that the frontend sometimes makes the same call so fast that the first call has not yet finished and I get errors like "collection was processed twice by flush()" and "failed to lazily initialize a collection of role: com.acme.model.Store, no session or session was closed" and "Flush during cascade is dangerous"

The different errors have all come from my different attempts at fixing the problem. I have tried to merge the account object, update the account object, etc.

I am using Thread-local sessions and have
<property name="current_session_context_class">thread</property>
in my hibernate.cfg.xml file. I can confirm the request come in on different threads but when I compare the session objects, they are sometimes the same and sometimes different (resulting in different errors)

Assuming I can not change the front end, what is the proper way to do this? Is storing the account object in the HttpSession a correct thing to do? How do I defend against this or is there some other fundamental flaw that I'm missing?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 02, 2009 1:37 am 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
Please see this if it helps:
http://forum.hibernate.org/viewtopic.php?p=2386276

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 02, 2009 10:28 am 
Newbie

Joined: Sun Mar 01, 2009 11:44 pm
Posts: 6
I had actually already looked over that thread but I didn't find it helpful for a few reasons.

1. The replies talk about calling flush when it shouldn't be. In my case, I am never calling flush, but I am calling session.commit, which under the thread-session setup, calls flush automatically.

2. I am not using seam or RichFaces and the (external link) solution is specific to those technologies.


There must be something I am fundamentally doing wrong. I have confirmed that the two requests DO happen on different threads, so I SHOULD get two distinct session objects, correct? If that is the case, how is it that calling commit (which triggers a flush and a close automatically) on the first session would have anything to do with the commit that happens on the 2nd thread, OR why would closing the first session also cause the second one to be closed?

The funny thing is that at one point in time I was getting errors about binding the same object to two different sessions but I don't get that anymore, nor can I seem to revert the code to a state that caused that either.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 02, 2009 9:57 pm 
Newbie

Joined: Sun Mar 01, 2009 11:44 pm
Posts: 6
I realize now that the errors I was getting yesterday were not the real problem. Yesterday's issue was the result of getting a Set from the database and converting it to an array, outside of the transaction (after the commit which closes the session)

i.e.
session.beginTransaction();
Set<Widget> widgets = m_accountDao.getWidgets(account);
session.commit();
return widgetArray = widgets.toArray(new Widget[]{});

It was actually the last line that converts the set to the array that was giving me the lazily initializing a set error since it was outside the transaction. Moving it inside / before the commit made the problem go away.

Now that I have fixed that, I'm getting "an unexpected exception: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions" everytime. This was the original error that I couldn't reproduce yesterday. Can anyone help me? Is there a way to see if an object is already associated to a session? and if so, what is the proper course of action then?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 02, 2009 11:03 pm 
Beginner
Beginner

Joined: Wed Dec 17, 2008 12:10 pm
Posts: 47
It is because you're working with the account object which is detached from the session. You'll need to merge the account object back into the session, or pull the collection by id rather than by the account object itself.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 03, 2009 12:39 pm 
Newbie

Joined: Sun Mar 01, 2009 11:44 pm
Posts: 6
Actually, I think the problem is the opposite. I AM calling session.merge(account) in my method.

I believe the issue is that since this is an ajax type application, two calls from the same client can come in 'near' simultaneously, but on different threads. Since it is different threads, when I call 'SessionFactory.getCurrentSession()', I do get two different sessions.

However, when the 2nd session.merge(account) is called (which happens before the first call ends), I get the error below.

example:

Code:
void getWidgets(Account account) {
     System.out.println("getWidget Start - Thread is: " + Thread.currentThread());
     beginTransaction();
     session = getSession();
     account = session.merge(account);
     getWidgets(account);
     commit();
     System.out.println("getWidget End");
}


What I see in the console then is:
Code:
getWidget Start - Thread is: Thread[HttpSession-2,5]
getWidget Start - Thread is: Thread[HttpSession-5,5]
getWidgetEnd
Exception org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions.


The exception is thrown on the 'merge' line.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 03, 2009 2:24 pm 
Newbie

Joined: Sun Mar 01, 2009 11:44 pm
Posts: 6
During my lunch hour, I looked at my code and I realized that I was calling

session.update(account) and not session.merge(account). That seemed to make a difference and I do not get the error now.

I was going from memory before.

Thanks.


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