72 Miles

Recent News

Archives

Enjoy our content? Please subscribe to read new content weekly.   
May 24, 2008 @ 2:38 pm

Spring: OpenSessionInViewInterceptor vs. OpenSessionInViewFilter

Problem: Assuming you’re using an ORM, such as Hibernate, rendering the view with business objects that have many-to-one or one-to-one relationships might try to access a detached object with a lazy property and throw a LazyInitializationException. For this reason, we’re provided with the Open Session In View pattern.


Solution: The Open Session In View pattern binds a Hibernate session to the thread to be used throughout the life of the request and closes any transactions when the response is sent. This is what allows your view to access model objects with lazily loaded properties after a transaction has been closed. This is nothing new and this is not what this post is about.

To setup the Open Session In View in your Spring application, you have two options. The OpenSessionInViewInterceptor and the OpenSessionInViewFilter. You can use either solution because the two classes serve the very same function and implement the same pattern. Well if this is the case, then why do they both exist? Why is there a filter option and an interceptor option? This is what I set to find out.

I’ve been searching Google all night. I’ve read through forums, I’ve read docs, and I’ve read blogs. Why? Because I want to use the better of the two options on my application. I want to ensure I am getting the best performance and the most reliability for my clients as I can. Anyway, the only thing that I could dig up was that they are equal in almost every way. The only consideration that you really need to make is what servlet spec you are using. If your servlet container support version 2.3 or later, you can use either one. If it’s 2.2 or earlier, you’ll need to go with the OpenSessionInViewInterceptor.

Surely there are other considerations. Maybe you want to keep your filters down to a bare minimum, or you think interceptors are confusing or messy. Or perhaps you like to keep your configuration files as small as possible. If you use annotations, you might want to go with the OpenSessionInViewInterceptor.

I hope I answered any questions you had about why there were two classes for implementing this pattern.

Now that you've read what we think, what did you like about the post? Where do you think we went wrong? Join or start the discussion.

Filed under Hibernate, Spring

About the Author

Mike Nereson has been a professional software developer since 2000. He thinks open source is rad, and is an active volunteer Fire Fighter.

8 Comments »

  1. Posted by jazzy

    May 24, 2008 @ 2:40 pm

    Hi, thanks for your post, it’s good to see that at least someone is writing about this stuff because I always feel a little worried if I’m using functionality that it appears no one else is using.

    There is an argument for OpenSessionInViewInterceptor that you have left out. If you want to keep a hard line separation between your model and your view, ie, data objects should never be passed to JSPs, and web forms should never be passed to the model, so you’re doing conversions in the controller, then you don’t want the session to be open to the JSPs, you want to intercept calls to the Actions, so that when the JSP is being rendered, the session is closed, and any LazyInitializationException is an indication that you are breaking your design pattern.

    Another reason for the existence of an OpenSessionInViewInterceptor is that web containers are not the only views to business objects, for example, you might have an MDP that receives a message, makes a call on your business object, gets some hibernate data objects back as results, and encodes them and sends a reply message. In this case the only option is OpenSessionInViewInterceptor.

  2. Posted by Robert Reiz

    August 20, 2008 @ 4:26 am

    Another example: If you are using a quartz-job in your service-layer with hibernateDAO access you got an Exception

    “No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here”

    with the openSessionInViewFilter. Because the openSessionInViewFilter is not active for actions startet on your service-layer. Here you need the openSessionInViewInterceptor.

  3. Posted by Ryan Stewart

    August 25, 2008 @ 8:50 am

    Actually, neither the Open Session In View Filter nor interceptor is the correct solution to your quartz problem. That exception is telling you that that your configuration won’t let you arbitrarily create a session. This is good, and is likely the result of configuring your HibernateTemplate with allowCreate=false. Using the Open Session In View pattern here would be a Bad Idea, as it simply ensures that a *non-transactional* session is available, which might allow your quartz job to complete successfully, but outside of a transaction, which could mean that nothing gets committed to the database, or it might just fail with a different exception. Worst case, it might mean that things are written to the database in auto-commit mode, meaning that other threads reading from the database could get corrupt data back. Operations performed by the service layer should be done within a transaction. This probably means that your services should be proxied with a TransactionInterceptor to handle your transactions. The TransactionInterceptor does *not* need an Open Session In View Filter or Interceptor, as it opens its own session if one is not available.

    A good example of when to use the Open Session In View Interceptor is one that jazzy gave: when processing messages or requests from something other than a person using a web page. You can actually consider the Open Session In View Filter as a specialized application of the Open Session In View Interceptor. It is useful only when a request comes to your application via a servlet container. If the request/message comes via other channels–say a message from a JMS queue–then the Open Session In View Filter is useless because it isn’t going through the Filter mechanism. That’s where you need the Open Session In View Interceptor (assuming that some response message is needed). Both filter and interceptor allow you to render a response outside of a transaction–that’s what the Open Session In View pattern is really about. The only distinction is that one is specific to a servlet environment, and one isn’t.

  4. Posted by Robert Reiz

    September 4, 2008 @ 3:54 am

    Hallo Ryan Stewart,

    sorry for my late response. I don’t use the HibernateTemplates, I am working with the genericDaos from Christian Bauer and annotation driven transaction management. The openSessionInViewInterceptor you can use with the property “singleSession=false”. It will not use a single session per request then, but rather let each data access operation or transaction use its own session (like without Open Session in View).
    But you are right and I was wrong. The TransactionInterceptor does not need an OpenSessionInViewFilter or Interceptor, as it opens its own session if one is not available. If I comment out the OpenSessionInViewInterceptor the quartz job works still fine, because I am using the @Transactional annotation in the service layer.

  5. Posted by Ryan Stewart

    September 4, 2008 @ 8:36 am

    If you’re using Spring and Hibernate, then you’re most likely using the org.springframework.orm.hibernate3.support.HibernateDaoSupport. If this is true and you don’t know that you’re using a HibernateTemplate, then you’re likely injecting this with a SessionFactory. The HibernateDaoSupport always uses a HibernateTemplate internally, though, whether you configure it explicitly or not. However, if this is how it’s being used, then it will default to allowCreate=true, so your “No Hibernate Session” exception is coming from something else that is not allowed to create a session. Normally using the Open Session In View pattern, in whatever incarnation, would prevent this, but, as you mentioned, setting singleSession=false removes this benefit, and it will go back to breaking because a session is not eagerly created when singleSession=false. Instead, everything is allowed/required to create its own session as needed, as if the pattern weren’t in use at all.

  6. Posted by Robert Reiz

    September 4, 2008 @ 2:52 pm

    I am not using the HibernateDaoSupport. I am using the org.springframework.orm.hibernate3.LocalSessionFactoryBean and inject it via “autowire=byName” in the my DAOs. My DAOs all extend the GenericDaoHibernate class from Christian Bauer. For the transactions I am using the org.springframework.orm.hibernate3.HibernateTransactionManager. My “No Hibernate Session” exception occurred because the @Transactional method was not listed in the Interface to my Service class. Since I added the method signature to the interface it works fine with and without OpenSessionInViewInterceptor/Filter.

  7. Posted by Ryan Stewart

    September 5, 2008 @ 3:35 pm

    The most prominent GenericDaoHibernate class I see is org.appfuse.dao.hibernate.GenericDaoHibernate. Is that what you’re using? It’s a direct subclass of HibernateDaoSupport. If not, then you’re probably doing stuff manually that this class automates for you.

  8. Posted by Robert Reiz

    September 6, 2008 @ 8:52 am

    Actually I’m using my own GenericDao class. I have take a look to org.appfuse.dao.hibernate.GenericDaoHibernate. It’s similar to my class. Perhaps in the next project I will use it. Thank you for the hint.

RSS feed for comments on this post · TrackBack URI

Leave a Comment

About

72 Miles Software - open source software, search engine optimization analytics, and software startup information. Software by design. Read More

Categories

Links

Sitemap