Today, a friend of mine asked me a question that he used the hibernate/spring/struts architecture, which was configured to use Spring's Opensessioninview Filter, but the discovery was not effective, The Lazy collection property still reports that the session has been closed when the page is accessed. I checked all the configuration and related code with him, but I didn't find any problems. After debugging, the application uses the session and Opensessioninview filter to open the session is not the same, so the Opensessioninview mode does not take effect, but why they do not use the same session.
Examined spring's related source code and found the root cause of the problem:
The configuration of spring is typically initialized in a Web application, and we will configure a listener in the web.xml, namely:
XML code
< listener >
< Listener-class >Org.springframework.web.context.ContextLoaderListener
</listener-class >
</Listener >
<listener>
<listener-class>org.springframework.web.context.contextloaderlistener</ Listener-class>
</listener>
If you use struts, you need to configure a spring plugin:contextloaderplugin in the configuration file Struts-config.xml of struts.
The functionality of the Contextloaderlistener and Contextloaderplugin is actually overlapping, and they are all initialized for the spring configuration. Therefore, if you do not intend to use Opensessioninview, then you do not need to configure Contextloaderlistener within the Web.xml.
OK, but now you need both the struts integration spring and the Opensessioninview pattern, the problem comes.
because the Contextloaderlistener and contextloaderplugin functions overlap, are initialized spring, you should not be initialized two times, so you should not use both, you can only choose one, Because you need to integrate struts now, you can only use Contextloaderplugin.
But it is puzzling that Contextloaderlistener and contextloaderplugin have a very contradictory place. The
Contextloaderlistener initializes the spring configuration and then places it in the ServletContext object to save:
Java code Servletcontext.setattribute ( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, This . context);;
Servletcontext.setattribute (
Webapplicationcontext.root_web_application_context_attribute, this.context);
Note that the key of the saved object is Webapplicationcontext.root_web_application_context_attribute.
But Contextloaderplugin initializes the spring configuration and then puts it in the ServletContext object to save:
Java code String attrname = Getservletcontextattributename ();; Getservletcontext ();. SetAttribute (Attrname, WAC);
String attrname = Getservletcontextattributename ();;
Getservletcontext ();. SetAttribute (Attrname, WAC);
This attrname is not the same as the Webapplicationcontext.root_web_application_context_attribute name.
If just the name is not the same, the problem is not much, you can still rest assured that the use of contextloaderplugin, but when you use Opensessioninview, Which key does the opensessioninviewfilter use to get the spring configuration?
Java code Webapplicationcontext WAC = Webapplicationcontextutils.getrequiredwebapplicationcontext (GETSERVL Etcontext (););;
Webapplicationcontext WAC =
Webapplicationcontextutils.getrequiredwebapplicationcontext (GetServletContext () ;);;
Obviously, Opensessioninviewfilter is based on the Webapplicationcontext.root_web_application_context_ Attribute this key to get the spring configuration.
Let's organize our thoughts:
Contextloaderplugin The name of the spring configuration is Attrname
, The Contextloaderlistener Save the spring configuration is called Webapplicationcontext.root_web_application_context_attribute;
And Opensessioninview the spring configuration according to the name Webapplicationcontext.root_web_application_context_attribute.
and your application is using the Attrname to get the spring configuration.
Therefore, the Opensessioninview mode fails.
Workaround:
Modify Contextloaderplugin Code, in Getservletcontext (). setattribute (Attrname, WAC); This place adds a line of code:
Getservletcontext (). setattribute (Webapplicationcontext.root_web_application_context_attribute, WAC);
or modify the Opensessioninviewfilter to get the spring configuration according to the Attrname.