-->
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.  [ 4 posts ] 
Author Message
 Post subject: Hibernate Query returning out-of-date data
PostPosted: Thu Jan 11, 2007 11:38 am 
Newbie

Joined: Thu Jan 11, 2007 11:24 am
Posts: 7
Dear all,

I have a very difficult problem to track down.

I have automatically generated Java classes by using MyEclipse’s Hibernate reverse engineering options. I have a JSP front-end, which allows the user to update and view data from this table.

I'm committing all my transactions etc. as appropriate.

The problem is that whilst the updates work ok, under Tomcat it appears that the data is being cached when I get data using a simple query (see below). If I refresh the web page, I can get different data back from each refresh, some of which is wrong (i.e. old data that is no longer in the database). Running the isame data access code on the command line, only the correct (new) version of the data is returned.

My suspicion is obviously with cached session data, and something about the way this is handled in the webserver environment. Not that I'm not using connection pools or datasources for this - the hibernate.cfg.xml is as follow:

Code:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
   <property name="connection.username">xx</property>
   <property name="connection.url">
   jdbc:sqlserver://localhost\sqlexpress:1433;databaseName=xx
         
   </property>
   <property name="dialect">
      org.hibernate.dialect.SQLServerDialect
   </property>
   <property name="connection.driver_class">
      com.microsoft.sqlserver.jdbc.SQLServerDriver
   </property>
   <property name="hibernate.max_fetch_depth">1</property>
   <property name="myeclipse.connection.profile">SQLServer</property>
   <property name="hibernate.show_sql">false</property>

  <property name="hibernate.cache.use_query_cache">false</property>
  <property name="hibernate.cache.use_second_level_cache">false</property>
  <property name="hibernate.connection.aggressive_release">false</property>
  <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!--
  thread is the short name for
            org.hibernate.context.ThreadLocalSessionContext
            and let Hibernate bind the session automatically to the thread

-->
<property name="current_session_context_class">thread</property>

   <mapping resource=......

</session-factory>

</hibernate-configuration>


I have tried to do all kinds of things whilst saving my object:


Code:
public void save(Object transientInstance, org.apache.commons.logging.Log log) {
          
          
              org.hibernate.Session s = getSession();
              org.hibernate.Transaction t = s.beginTransaction();
               try {
              s.save(transientInstance);
              s.flush();
               t.commit();
               s.refresh(transientInstance);
               s.clear();
              
              s.close();
……


But nothing works. When accessing the data via the following method, I often get old data:

Code:
private Query getX() {
      Session s = getSession();
      Query q = null;

      try {
         q = s.createQuery("from X as e "
               + "order by e.y.name, e.ordernum, e.name");
      } catch (HibernateException e) {
         e.printStackTrace();
         s.close();
      }
      
      return q;
   }


FYI, I am obtaining the session via the automatically generated HibernateSessionFactory:
Code:
public static Session getSession() throws HibernateException {
        [b]Session session = (Session) threadLocal.get();[/b]

      if (session == null || !session.isOpen()) {
         if (sessionFactory == null) {
            rebuildSessionFactory();
         }
         session = (sessionFactory != null) ? sessionFactory.openSession()
               : null;
         threadLocal.set(session);
      }

        return session;
    }

Finally, the mapping for my Class X is as follows:

Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="enjoy.hibernate.X" table="X " schema="dbo" catalog="xx">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>



        <many-to-one name="Y" class="enjoy.hibernate.Y" fetch="select">
            <column name="primary_area_id" not-null="true" />
        </many-to-one>
        <set name="Z" inverse="true">
            <key>
                <column name="secondary_area_id" not-null="true" />
            </key>
            <one-to-many class="enjoy.hibernate.Z" />
        </set>


</hibernate-mapping>

I am using SQL Server, but I have no reason to believe it would be any different using a different database.

I’ve looked at many forums, e.g. the posting at http://forum.hibernate.org/viewtopic.php?t=968417&highlight=cache, but I cannot see an answer to my problems.

Has anybody got any suggestions?

Cheers

Jonny


Top
 Profile  
 
 Post subject: Hmm
PostPosted: Thu Jan 11, 2007 1:12 pm 
Newbie

Joined: Thu Jan 11, 2007 11:24 am
Posts: 7
This forum is depressing..as many people have looked at "Free Adiult Video" as have looked at this posting.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 3:05 pm 
Regular
Regular

Joined: Wed Dec 07, 2005 4:19 pm
Posts: 53
I assume you are not closing your session between individual server requests, hence each thread-session caches the last value.

However, I believe that Tomcat is using a thread pool - meaning that each request gets a thread from the pool, and then returns this thread back.
Quote:
"The solution for these problems is to use a thread pool, which is the default for Tomcat 3.2."


This means that you may get a 'recycled' thread, which caches your 'old' Session, which then caches your 'old' value.
In addition, you probably never close your thread sessions this way...

I would try closing and discarding thread session in each request, and when that helps then I would look for some sorts of optimization.
Turning off Tomcat thread pooling would accomplish that as well, but why turning off a usefull optimization?

For example, (I know this is a bit unusual - see below) you could cache certain sessions by your (object hierarchy) main key - of course, then you have synchronization issues, but at least you can share your data between multiple requests, and any data change becomes immediatelly visible to all threads.

{ Note that with Hibernate, you must think about what are you putting into your Session, as each transaction will commit ALL changes to ALL objects in that Session. So sometimes, one may need multiple Sessions within one 'conversation'. }



Don't forget to rate this reply (if it helped).


Top
 Profile  
 
 Post subject: Problem solved
PostPosted: Fri Jan 12, 2007 10:34 am 
Newbie

Joined: Thu Jan 11, 2007 11:24 am
Posts: 7
Thanks.

Your suggestion put me on the right path. I found an article on the serverside:
http://www.theserverside.com/news/thread.tss?thread_id=42557#220147.

This comment was of particular use:

Quote:
if you are using sessionFactory.getCurrentSession()(and it's configured to use ThreadLocalSessionContext which probably makes sense if one is just using Tomcat 5.5 and not a full server with JTA), then a call to sessionFactory.getCurrentSession().close() in a servlet filter should clean things up properly in a session-per-request strategy (user just has to call it, Hibernate knows what ThreadLocal vars it created and will clean it properly).

So I wrote a Filter, and made it close the Session after calling chain.doFilter(). Evidently, not all my Sessions were being closed before this.

And this sorted out my problem.

Thanks

Jonny


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