aspose file tools*
The moose likes Object Relational Mapping and the fly likes Transaction Dermacation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Transaction Dermacation" Watch "Transaction Dermacation" New topic
Author

Transaction Dermacation

Songezo Nkukwana
Ranch Hand

Joined: Nov 27, 2008
Posts: 51
Hi, working on a struts-web application using hibernate persistence tool. Since we using tomcat, my colleague suggest that we should avoid JTATransaction management and use default JDBCTransaction. We both a re new to hibernate and not sure where to demarcate out code with transactions. I have DAOs and service classes, then action classes. We plan to use the Hibernate session-per-request pattern with threadLocal configured with a context (can't say i understand much of that) i.e this ..

is configured within hibernate config file. My question is where exactly should the code session.beginTransaction() go? Here's my service class


Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper

Joined: Aug 26, 2006
Posts: 4968
    
    1

Create a filter for your struts servlet and start it before and after the struts servlet is inovked. That's the easiest way. It's known as the 'open session in view' pattern, and will work so long as your web and ejb tier are on the save layer.

Hibernate and JPA Open Session In View Pattern

Whatever you do, do NOT do it in your DAOs. That's a rookie mistake.

-Cameron McKenzie
Songezo Nkukwana
Ranch Hand

Joined: Nov 27, 2008
Posts: 51
Cameron Wallace McKenzie wrote:Create a filter for your struts servlet and start it before and after the struts servlet is inovked. That's the easiest way. It's known as the 'open session in view' pattern, and will work so long as your web and ejb tier are on the save layer.

Hibernate and JPA Open Session In View Pattern

Whatever you do, do NOT do it in your DAOs. That's a rookie mistake.

-Cameron McKenzie


I read this -> http://www.theserverside.com/tt/articles/article.tss?l=HibernateTomcat which seems to discourage getting sessions from thread using getCurrentSession(). It suggests that one should always open a new session ...

There is one further point we wish to make about the above servlet. Notice the following line of code near the top of the method doQuery():

Session session = HibernateUtil.getSessionFactory().openSession();

We could have chosen the following alternative syntax - but we would never choose to do so with Tomcat:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();


Why would we never use this alternative syntax with Tomcat? The difference between openSession() and getCurrentSession() is that the former, each time it is used, provides a brand new Hibernate Session. That is exactly what we want in our servlet. In contrast, getCurrentSession attempts to associate a Hibernate Session with a specific thread (the Singleton-per-Thread pattern), which Hibernate achieves via the use of an embedded (hidden) ThreadLocal. Unfortunately, Tomcat maintains a thread pool, and re-uses a given thread after a particular Http request is finished with it. Hence a brand new Http request can receive a previously used thread, which already happens to have a Hibernate Session associated with it (via the ThreadLocal), and getCurrentSession() may by chance receive an unrelated Hibernate Session when it ought to receive a brand new one. We may have a new Http session, and logically a new thread, but physically be re-using an existing thread. In this way, Tomcat 5.5.x and Hibernate 3.1 can confuse each other.

We choose to bypass the issue entirely by using SessionFactory.openSession, and avoiding the use of SessionFactory.getCurrentSession in a Tomcat environment.

The conflict we described above is readily testable. Setup a Tomcat 5.5 environment allowing only a small number of concurrent threads - say 3 or 4. (You accomplish this via an entry in Tomcat Root\conf\server.xml, namely by setting the maxThreads attribute of the applicable <Connector> element in this file to 3 or 4.) Create a couple of distinct, simplistic business transactions (conversational transactions or long-running transactions) which span Http requests. Attempt to preserve information in a ThreadLocal - any information �'�it doesn�'�t need to have anything to do with Hibernate - and do some tracing/logging in which you display the thread ID. You will see Tomcat thread pooling eventually recycle thread IDs to another business transaction, allowing inappropriate access to the ThreadLocal contents to take place.


Isn't Filter's or Interceptor Servlets exists to help achieve lazy loading?
 
jQuery in Action, 2nd edition
 
subject: Transaction Dermacation