• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Transaction Dermacation

 
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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


 
author and cow tipper
Posts: 5009
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic