Posts Mentioning RSS Toggle Comment Threads | Keyboard Shortcuts

  • Mike 8:48 pm on June 5, 2008 Permalink | Reply  

    Spring: Loading Multiple Contexts 


    I have already argued that many application contexts are better than a single application context. But how the heck do you load more than one context?

    There are a couple of ways to do this.

    web.xml

    Your first option is to load them all into your Web application context via the ContextConfigLocation element. You’re already going to have your primary applicationContext here, assuming you’re writing a web application. All you need to do is put some white space between the declaration of the next context.

    <context-param>
        <param-name>
            contextConfigLocation
        </param-name>
        <param-value>
            applicationContext1.xml
            applicationContext2.xml
        </param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    

    The above uses carriage returns. Alternatively, yo could just put in a space.

    <context-param>
        <param-name>
            contextConfigLocation
        </param-name>
        <param-value>
            applicationContext1.xml applicationContext2.xml
        </param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    

    applicationContext.xml

    Your other option is to just add your primary applicationContext.xml to the web.xml and then use import statements in that primary context.

    In applicationContext.xml you might have…

    <!-- hibernate configuration and mappings -->
    <import resource="applicationContext-hibernate.xml"/>
    
    <!-- ldap -->
    <import resource="applicationContext-ldap.xml"/>
    
    <!-- aspects -->
    <import resource="applicationContext-aspects.xml"/>
    

    Which Strategy?

    I always prefer to load up via web.xml This allows me to keep all contexts isolated from each other. With tests, we can load just the contexts that we need to run those tests. This makes development more modular too as components stay loosely coupled, so that in the future I can extract a package or vertical layer and move it to its own module.

    Any benefits to going with the application context import method?

     
    • Juliet 7:43 am on November 20, 2008 Permalink

      How to map dispatcher servlet, for multiple applicationContext?.
      Can you give me the solution.

    • Mike 8:20 am on November 20, 2008 Permalink

      @Juliet – Define the mappings in your applicationContext.xmls, then include those contexts in the web.xml as described in this post. Make sure that none of the beans have the same name or they will be overwritten as each context is loaded.

      If you have further questions about this I would recommend the spring forum over a comment in a blog.

  • Mike 5:49 pm on May 24, 2008 Permalink | Reply  

    Spring: Many applicationContext.xml > One applicationContext.xml 

    This is a short introduction to splitting up your bean definitions from one single Spring application context, to many application contexts. That is, from one XML file to many XML files.

    The general idea is to have one single primary application context, usually titled
    applicationContext.xml, and then many other application contexts with are named what they contain.

    Example

    • applicationContext.xml
    • applicationContext-dao.xml
    • applicationContext-dao-datasource.xml
    • applicationContext-ldap.xml
    • applicationContext-aspects.xml
    • applicationContext-web.xml

    Breakdown

    In this example, your DAO definitions, transaction managers, and DAO or integration interceptors are defined in applicationContext-dao.xml. We have further broken the DAO application context to a dao-datasource which contains our data sources. LDAP configuration, beans, and DAOs are in their own applicationContext-ldap.xml.

    Benefits

    Why so many? There have been a few benefits so far.

    • Clearly, working with a smaller XML file is easier than working with one enormous file. It is easier to maintain and easier to read.
    • Testing. When I wrote my tests for LDAP, I had my LDAP configuration in applicationContext.xml, but then every time I ran an LDAP test, I would get the WebApplicationContext, which would import applicationContext-hibernate, which would connect to the database, tests took forever, needless resources used… Anyway, now I just get applicationContext-ldap.xml which only contains LDAP configurations, so no needless resources are loaded.
    • Including. Finally, its really easy to comment out a line like
      <import resource="applicationContext-aspects.xml"/>

      and quickly have all my aspects, which for me only write logs, disabled.

    Does anyone else use multiple application context files? See any other benefits? Or problems?

     
    • Jamo Smith 5:52 pm on May 24, 2008 Permalink

      I’ve used a folder called springbeans to hold all my context files. They are module or entity centric:

      - user.xml
      - project.xml
      - hibernate.xml
      - security.xml

      Tests are able to isolate only 1 or 2 contexts that are required to do the given test.

    • cherouvim 5:53 pm on May 24, 2008 Permalink

      Yep. Many files and imports is how I prefer it as well. Especially those which are deployment related (datasource, mail session details etc).

      And I see no problems with that.

    • Ashkan 5:53 pm on May 24, 2008 Permalink


      Clearly, working with a smaller xml file is easier than working with one enormous file.

      And working with as little as possible XML stuff is the utopia so take a look at Guice Mike.

    • Peter Warhol 2:23 pm on May 25, 2008 Permalink

      I think that was covered recently in the 90th percentile:
      http://icoloma.blogspot.com/2008/01/mock-your-spring-config-for-fun-and.html

    • Mike 9:19 am on May 26, 2008 Permalink

      Thank you Peter. the 90th percentile states

      This is an old habit of mine, a “main index file” that imports everything else. It is a bit cleaner than specifying every file in the web.xml descriptor

      and follows up that with an example of how to import many application contexts into a main one.

    • Matt 9:55 am on May 27, 2008 Permalink

      Another issue we ran into is having several applicationContext.xml on the classpath leads to some very hard to track errors. By giving the file a unique name, you can help avoid these conflicts.

    • Adrian Neagomir 10:14 am on May 27, 2008 Permalink

      I use two definition files when doing web applications with Spring: one containing the database access and the service layer while the web related stuff in the configuration file that’s used to configure the DispatcherServlet.

      The advantage of having this setup is that I can instantiate a console application that has access to the entire service layer for batch jobs, tests etc. using only the first file without having any dependency to a servlet container.

      Using more files one can assemble different application using the same codebase.

    • Max Power 6:15 pm on May 28, 2008 Permalink

      Splitting your bean definitions into multiple files is definitely a good practice. However, regarding how your old way of not splitting it up caused the app context to connect to the database reminds me of something I read where I believe the preferred way of coding unit tests is to create the beans programmaticly in the setup methods. This way the tests aren’t tied to configuration files that may be changed, causing the tests to become invalid since they aren’t being run in the same configuration against which they were coded.

    • Mike 7:45 am on May 29, 2008 Permalink

      Max, good points on test datasouces. With a Spring context, you could create a datasource bean with the same name, and then load that test context AFTER the production context, the test context would be used. That way you can keep all the configuration in the application contexts and have them injected.

    • Andrew Sazonov 1:44 am on June 7, 2008 Permalink

      Just my 2 cents – suggestion from Mike regarding testing via bean overriding (i.e registering bean in text context using the same name as one in production) will work, but only if context is configured to allows bean definition overriding (there is appropriate setting for that)

  • Mike 2:48 pm on May 24, 2008 Permalink | Reply  

    Spring: OpenSessionInViewInterceptor & OpenSessionInViewFilter Examples 

    This post on OpenSessionInViewInterceptor vs. OpenSessionInViewFilter gets a lot of views from developers who are searching “OpenSessionInViewFilter” and “OpenSessionInViewFilter”. I’d guess, a lot of them are looking for examples. I don’t want to disappoint anyone so here are example setups of both the filter and the interceptor.

    OpenSessionInViewInterceptor

    This goes into your action-servlet.xml.

    <beans>
    
    <bean id="urlMapping"
    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    
    <property name="interceptors">
    <list>
    <ref bean="openSessionInViewInterceptor"/>
    </list>
    </property>
    
    <property name="mappings">
    
    </bean>
    
    <bean name="openSessionInViewInterceptor"
    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    
    <property name="sessionFactory">
    <ref bean="sessionFactory"/>
    </property>
    </bean>
    
    </beans>
    

    OpenSessionInViewFilter

    This goes into your web.xml.

    <web-app>
    
    <filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    
    <filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>*.html</url-pattern>
    </filter-mapping>
    
    </web-app>
    

    If you are not sure if you need to use the filter or the interceptor, check our post that explains the “>difference between the OpenSessionInViewFilter and the OpenSessionInViewInteceptor. The comments on that page offer some good insight too.

     
    • Anonymous 2:49 pm on May 24, 2008 Permalink

      Thanks.

    • Anonymous 2:49 pm on May 24, 2008 Permalink

      thanks a lot! code is better than 1000 blog post! :D

    • Mike 2:50 pm on May 24, 2008 Permalink

      Too true. I hate going to software blogs and seeing nothing but paragraph after paragraph. I want to see code that I can copy and paste, that has comments in it so that I can follow it.

      Glad I could help. Cheers.

    • cookie 2:51 pm on May 24, 2008 Permalink

      Hi Mike,
      Kudos on the great explanations and examples.

      I am a newbie to Spring (as well as Java :P ). I have a question regarding OpenSessionInViewInterceptor/ Filter.

      I have a Spring app that only selective controllers requires open sessions. Can I selectively “hook-up” the interceptor to those controllers?

      Thanks a lot.

      YS

    • Anonymous 2:51 pm on May 24, 2008 Permalink

      For those of you using the Persistence API, there is also an EntityManager version:

      org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor

      Thanks for your example, Chris

      PS I would put an example – but seems the comments box does not allow it :(

    • weggyboy 2:52 pm on May 24, 2008 Permalink

      Nice Post, but it only works for views, doesn´t it?

      I was trying to change some entries after the proposed changes and found out, that the write operations are not allowed with the default session setting for the openViewInSession filter.
      After searching for a solution I´ve found that:

      import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
      import org.hibernate.*;
      import org.springframework.dao.*;

      public class SessionFilter extends OpenSessionInViewFilter {
      /*
      * The default mode is FlushMode.NEVER
      *
      * @see org.springframework.orm.hibernate.support.OpenSessionInViewFilter#getSession(net.sf.hibernate.SessionFactory)
      */
      protected Session getSession(SessionFactory sessionFactory)
      throws DataAccessResourceFailureException {
      Session session = super.getSession(sessionFactory);
      session.setFlushMode(FlushMode.COMMIT);
      return session;
      }

      /**
      * we do an explicit flush here just in case we do not have an automated flush
      */
      protected void closeSession(Session session, SessionFactory factory) {
      session.flush();
      super.closeSession(session, factory);
      }
      }

      Now it works as wished!

    • delta one 2:53 pm on May 24, 2008 Permalink

      Excellent example!

    • Dan Allen 3:21 pm on May 24, 2008 Permalink

      You should read Spring in Seam, Part 3 (http://www.javaworld.com/javaworld/jw-05-2008/jw-05-spring-seam3.html) and chapters 8 and 9 of Seam in Action to discover why this Spring filter/interceptor is essential a huge *hack*. The persistence manager (Hibernate Session/JPA EntityManager) was designed to be extended across a series of requests, not be relegated to a single request or worse service layer call. LazyInitializationExceptions happen because the persistence manager is scoped incorrectly.

    • David Newcomb 12:28 pm on October 12, 2009 Permalink

      Your xml for urlMapping is incomplete! No value is set for:

      and the property is closed. What is it supposed to be?

    • David Newcomb 12:29 pm on October 12, 2009 Permalink

      Your xml for urlMapping is incomplete! No value is set for:
      property name=”mappings”
      and the “property” is not closed. What is it supposed to be?

    • David Newcomb 1:51 pm on October 12, 2009 Permalink

      Also urlMapping doesn’t work if you are using annotations.
      If you are using annotations you should probably go for the OpenSessionInViewFilter otherwise there is a rats nest of other support classes you need. Just spent the day reading all about it and I have lost the will to live :(

    • Mike 9:25 am on October 13, 2009 Permalink

      @David Newcomb – The post isn’t really about how to set mappings. But you’ll want something like

      installController

      which maps a request URI to a controller. Here are some examples…

      http://www.google.com/search?q=SimpleUrlHandlerMapping+example

    • Pieno 7:52 am on July 11, 2010 Permalink

      In Spring 3 you can use the tag to use the OpenSessionInViewInterceptor. There is an example on my blog: http://www.pieno.be/content/2010/opensessioninviewinterceptor-example-spring-3-web-mvc

  • Mike 2:38 pm on May 24, 2008 Permalink | Reply  

    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.

     
    • jazzy 2:40 pm on May 24, 2008 Permalink

      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.

    • Robert Reiz 4:26 am on August 20, 2008 Permalink

      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.

    • Ryan Stewart 8:50 am on August 25, 2008 Permalink

      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.

    • Robert Reiz 3:54 am on September 4, 2008 Permalink

      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.

    • Ryan Stewart 8:36 am on September 4, 2008 Permalink

      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.

    • Robert Reiz 2:52 pm on September 4, 2008 Permalink

      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.

    • Ryan Stewart 3:35 pm on September 5, 2008 Permalink

      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.

    • Robert Reiz 8:52 am on September 6, 2008 Permalink

      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.

    • Charles Gutjahr 1:26 am on November 11, 2008 Permalink

      I have found it necessary to choose OpenSessionInViewInterceptor over OpenSessionInViewFilter when using Spring Web Flow (SWF).

      If you use the filter (OpenSessionInViewFilter) then all requests will have the Hibernate session applied to them, regardless of whether Spring MVC, Spring Web Flow or something else handles the request. This is a problem if you use Spring Web Flow’s flow managed persistance (ie the tag) because it creates its own Hibernate session… this results in two sessions being created and a pile of IllegalStateExceptions because only one session is allowed.

      OpenSessionInViewInterceptor solves this problem because you can choose to apply it only to some handlers – ie apply it to Spring MVC but don’t apply it to Spring Web Flow. That way you can use OpenSessionInViewInterceptor for Spring MVC where it is very useful — and let Spring Web Flow use its (probably superior) flow managed persistance for Spring Web Flow handlers.

    • Mike 9:20 pm on November 11, 2008 Permalink

      @Charles Gutjahr – Charles, thanks for sharing that use case. I use and love Spring MVC, but have not had the opportunity to get into web flow yet. Thanks for describing the situation that you encountered and why the interceptor was the solution. I’m sure that comment will be very helpful to someone soon.

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
esc
cancel