views:

98

answers:

2

I am getting this exception in a controller of a web application based on spring framework using hibernate. I have tried many ways to counter this but could not resolve it.

In the controller's method, handleRequestInternal, there are calls made to the database mainly for 'read', unless its a submit action. I have been using, Spring's Session but moved to getHibernateTemplate() and the problem still remains.

basically, this the second call to the database throws this exception. That is:

1) getEquipmentsByNumber(number) { firstly an equipment is fetched from the DB based on the 'number', which has a list of properties and each property has a list of values. I loop through those values (primitive objects Strings) to read in to variables)

2) getMaterialById(id) {fetches materials based on id}

I do understand that the second call, most probably, is making the session to "flush", but I am only 'reading' objects, then why does the second call throws the stale object state exception on the Equipment property if there is nothing changed?

I cannot clear the cache after the call since it causes LazyExceptions on objects that I pass to the view.

I have read this: https://forums.hibernate.org/viewtopic.php?f=1&t=996355&start=0 but could not solve the problem based on the suggestions provided.

how can I solve this issue. Any ideas and thoughts are appreciated.

UPDATE: What I just tested is that in the function getEquipmentsByNumber after reading the variables from list of properties, I do this: getHibernateTemplate().flush(); and now the exception is on this line rather then the call to fetch material (that is getMaterialById(id)).

UPDATE: Before explicitly calling flush, I am removing the object from session cache so that no stale object remains in the cache. getHibernateTemplate().evict(equipment); getHibernateTemplate().flush();

OK, so now the problem has moved to the next fetch from DB after I did this. I suppose I have to label the methods as synchronized and evict the Objects as soon as I am finished reading their contents! it doesn't sound very good.

UPDATE: Made the handleRequestInternal method "synchronized". The error disappeared. Ofcourse, not the best solution, but what to do! Tried in handleRequestInternal to close the current session and open a new one. But it would cause other parts of the app not to work properly. Tried to use ThreadLocal that did not work either.

A: 

This problem was something that I had experienced and was quite frustrating, although there has to be something a little odd going on in your DAO/Hibernate calls, because if you're doing a lookup by ID there is no reason to get a stale state, since that is just a simple lookup for an object.

First, make sure all your methods are annotated with @Transaction(required=true) // you'll have to look up the exact syntax

However, this exception is usually thrown when you try to make changes to an object that has been detached from the session it was retrieved from. The solution to this is often not simple and would require more code posted so we can see exactly what is going on; my general suggestion would be to create a @Service that performs these kinds of things within a single transaction

walnutmon
Thanks for the suggestion. What I just tested is that in the function getEquipmentsByNumber after reading the variables from list of properties, I do this:getHibernateTemplate().flush(); and now the exception is on this line rather then the call to fetch material (that is getMaterialById(id))I am not using annotations since I am not very much familiar with it.
Saky