Take the 2-minute tour ×

I'm using Hibernate behind of a JSF project.

In the main page, i have a datatable representing a list of objects.

I successfully make an update on a property of an object (found in the datatable) using Hibernate. After update, page is refreshed by redirecting using "xxx?faces-redirect=true". I redirect the page to avoid "duplicate form submission" kind problems.

Then, if i hit F5 several times, old property value of updated object might come back to the page.

As i understand this is an Hibernate session problem. Because if i close immidiately every session after they are used, this problem doesn't occur. However, due to lazy fetching strategy, i can't close the sessions after the transactions.

Briefly, hibernate might bring old value of an object although it has been successfully updated. How can i avoid such problem?

ps: I suspected about caching mechanisms of Hibernate, and i disabled first and second level cache using:

<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.use_second_level_cache">false</property>

but it didn't work too..

Update: After the reply of @Johanna, i controlled ids of session instances and remarked that my HibernateUtil class returns a different session in most of the time or opens a new session. Here is the getSession() method:

public static Session getSession(){
    Session se = HibernateUtil.session.get();
    if(se == null)
        se = sessionFactory.openSession();
    return se;

I was supposing that once i have a session, i make everything such listing, updating, etc. with that session. Because i make the necessary controls in the getSession() method. Where do i make a mistake?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Neither use_query_cache nor use_second_level_cache can disable the first level cache. The first level cache always is on.

If you really do not want to use the first level cache, then you have to use StatelessSession instead of Session. But StatelessSession has less functionality and some of the methods you need might be missing.

If you only want to remove a few objects from the first level cache, you can use Session.evict().

Nevertheless I wonder why Hibernate presents the old value to you. This should not happen if each database entity only has one instance in the session (i. e. the instance of the object which you update is the same instance as shown in the list). If you use two different instances, then it is normal Hibernate presents the old value (and if you use two Session instances, one for the list and one for the update, then also you get the old value in the list). So perhaps you don't have to evict the object when you fix your application.

EDIT after your update: In your short codelet I can't see why you get errors if you as a single user use the application.

But generally: You use JSF, so it is probably a web project which can be used by many users.

The Hibernate Session object is not thread-save, i. e. it probably won't work if different users use it at the same time. Each user needs its own session object. So you can store the Hibernate session instance in the Http session instance (and even then sometimes you must use 'synchronized' methods (or objects) just for the case the user presses a second time on a button before the answer from the first request arrived).

2nd EDIT: I think you have the same problem as in this question.

Probably you copied your code from anywhere like the DAO of the cited question. I guess your HibernateUtil class, whose code you copied from anywhere, stores the hibernate session in a ThreadLocal object, i. e. one hibernate session is bound to one thread.

But you're doing a web project. There you should bind one Hibernate session to one user (or browser), i. e. to one Http session. But you do not know in which thread the request from one http session is processed. Thus in your solution the same Http session may get different Hibernate sessions or perhaps different Http sessions may get the same Hibernate session. This depends to your Http server.

Solution: Put the Hibernate session into the Http session (and do not use the ThreadLocal object). You get the Http session object with HttpServletRequest.getSession() and with HttpSession.getAttribute()/HttpSession.setAttribute() you can set the Hibernate session and other Http session related data.

share|improve this answer
I make a control to avoid having two different sessions. So if there is an open session, i don't create another, i return the open session. Hence, there should not exist two different sessions. Is it a problem to make use an existing session while listing, updating, etc. –  Cihan Aksoy Apr 18 '12 at 6:27
It should work with only one session. I recommend to you to start your application in the debug mode and check whether the instance which you update and the instance where you get the old value are the same instance (the addresses or the instance ids in the Eclipse debugger are equal) –  Johanna Apr 18 '12 at 7:42
I chekced ids as you said, and i needed to update the question with my observations. Waiting for your helps, thanks.. –  Cihan Aksoy Apr 18 '12 at 10:28
Please see my edited answer above –  Johanna Apr 18 '12 at 10:55
After have read your reply, i can say that i make tests as a single user for now. As a single user, why do i get different sessions from getSession() method? Is there a problem with that method? –  Cihan Aksoy Apr 18 '12 at 11:21
show 3 more comments

Your Answer


