Spring 3.2 + Hibernate 4 OpenSessionInViewFilter [英] Spring 3.2 + Hibernate 4 OpenSessionInViewFilter

查看:79
本文介绍了Spring 3.2 + Hibernate 4 OpenSessionInViewFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一位春季新手,正在尝试我的第一个应用程序。我的hibernate在渲染视图之前就会关闭,并且会遇到延迟加载属性(预期行为)的问题。我已经将OpenSessionInViewFilter添加到了我的web.xml中,并导致了以下结果:

  java.lang.IllegalStateException:找不到WebApplicationContext:没有ContextLoaderListener注册? 

事先使用默认的servlet context配置我可以正常工作(有人可以告诉我为什么?)。所以我添加了以下内容:

 < context-param> 
< param-name> contextConfigLocation< / param-name>
< param-value>
/WEB-INF/springapp-servlet.xml
< /参数值>
< / context-param>

< listener>
< listener-class> org.springframework.web.context.ContextLoaderListener< / listener-class>
< / listener>

新的错误消失了,但是仍然没有从休眠中获得会话异常

  org.hibernate.LazyInitializationException:无法延迟初始化角色集合:com.test.model.Store.categories,无法初始化代理 -  no Session 

我在我的一个控制器中放了一条调试消息,它似乎正在初始化3倍。也许我有多个hibernate会话工厂bean的实例?我的控制器方法被标记为@Transactional,并且一直运行,直到我试图离开会话以使该视图的惰性字段可用。



我的完整web.xml (添加了新的上下文,在添加了hibernate过滤器之前没有它,工作正常):

 <?xml version =1.0encoding =ISO-8859-1?> 

< web-app version =2.4
xmlns =http://java.sun.com/xml/ns/j2ee
xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation =http://java.sun.com/xml/ns/j2ee
http:// java。 sun.com/xml/ns/j2ee/web-app_2_4.xsd>
< display-name>
Spring
< / display-name>
< description>
Spring Test
< / description>

< context-param>
< param-name> contextConfigLocation< / param-name>
< param-value>
/WEB-INF/springapp-servlet.xml
< /参数值>
< / context-param>

< listener>
< listener-class> org.springframework.web.context.ContextLoaderListener< / listener-class>
< / listener>

< filter>
< filter-name> hibernateFilter< / filter-name>
< filter-class> org.springframework.orm.hibernate4.support.OpenSessionInViewFilter< / filter-class>
< init-param>
< param-name> sessionFactoryBeanName< / param-name>
< param-value> sessionFactory< / param-value>
< / init-param>
< / filter>

< filter-mapping>
< filter-name> hibernateFilter< / filter-name>
< url-pattern> / *< / url-pattern>
< dispatcher> REQUEST< / dispatcher>
< dispatcher> FORWARD< / dispatcher>
< / filter-mapping>

< servlet>
< servlet-name> springapp< / servlet-name>
< servlet-class> org.springframework.web.servlet.DispatcherServlet< / servlet-class>
1< / load-on-startup>
< / servlet>



< servlet-mapping>
< servlet-name> springapp< / servlet-name>
< url-pattern> /< / url-pattern>
< / servlet-mapping>

<错误页面>
<错误代码> 500< /错误代码>
< location> / error / 500< / location>
< / error-page>
<错误页面>
< error-code> 404< / error-code>
< location> /resources/pages/error.html< / location>
< / error-page>



< / web-app>

springapp-servlet.xml

 <?xml version =1.0encoding =UTF-8?> 

< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema -instance
xmlns:context =http://www.springframework.org/schema/context
xmlns:mvc =http://www.springframework.org/schema/mvc
xmlns:aop =http://www.springframework.org/schema/aop
xmlns:tx =http://www.springframework.org/schema/tx
xsi :schemaLocation =http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http:// www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/上下文
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http:/ /www.springframework.org/s chema / tx / spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop- 3.2.xsd>

< context:component-scan base-package =com.test.web.controllers,com.test.service.impl/>

< mvc:annotation-driven />
< mvc:resources mapping =/ resources / **location =/ resources //>

< bean id =myDataSourceclass =org.apache.commons.dbcp.BasicDataSourcedestroy-method =close>
< property name =driverClassNamevalue =com.mysql.jdbc.Driver/>
< property name =usernamevalue =spring/>
< property name =passwordvalue =test/>
< / bean>

< bean id =sessionFactoryclass =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =myDataSource/>
< property name =mappingLocationsvalue =classpath *:com / test / model / hbm / ** / *。hbm.xml/>

< property name =hibernateProperties>
<值>
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql = true
< / value>
< / property>
< / bean>

< tx:annotation-driven />
< bean id =transactionManager
class =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>


< bean id =velocityConfigclass =org.springframework.web.servlet.view.velocity.VelocityConfigurer>
< property name =resourceLoaderPathvalue =/ WEB-INF / templates //>
< / bean>
< bean id =viewResolverclass =org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver>
< property name =cachevalue =true/>
< property name =prefixvalue =/>
< property name =suffixvalue =。vm/>
< property name =layoutUrlvalue =index.vm/>

<! - 如果您想使用Spring Velocity宏,请将此属性设置为true - >
< property name =exposeSpringMacroHelpersvalue =true/>

< / bean>

< bean id =multipartResolver
class =org.springframework.web.multipart.commons.CommonsMultipartResolver>

<! - - 其中一个可用的属性;最大文件大小(以字节为单位) - >
< property name =maxUploadSizevalue =10000000/>
< / bean>

< bean id =validatorclass =org.springframework.validation.beanvalidation.LocalValidatorFactoryBean/>

< bean id =categoryDAOclass =com.test.dao.hibernate.HibernateCategoryDAO>
< property name =sessionFactoryref =sessionFactory>< / property>
< / bean>
< bean id =categoryServiceclass =com.test.service.Categoriesscope =singleton>
< property name =daoref =categoryDAO>< / property>
< / bean>
< bean id =storeDAOclass =com.test.dao.hibernate.HibernateStoreDAO>
< property name =sessionFactoryref =sessionFactory>< / property>
< / bean>
< bean id =storeServiceclass =com.test.service.Storesscope =singleton>
< property name =daoref =storeDAO>< / property>
< property name =categoryDaoref =categoryDAO>< / property>

< / bean>

< / beans>


解决方案

我的控制器初始化了两次,使用了相同的配置由根ApplicationContext和由FrameworkServlet。我有两个初始化的上下文。我创建了一个名为springapp.xml的根上下文的配置,并将所有中间层配置移动到那里,并将我的web层配置留在springapp-servlet.xml中。



我的web.xml现在看起来像这样,一切正常:

 < context-param> 
< param-name> contextConfigLocation< / param-name>
< param-value>
/WEB-INF/springapp.xml
< /参数值>
< / context-param>

< listener>
< listener-class> org.springframework.web.context.ContextLoaderListener< / listener-class>
< / listener>

< filter>
< filter-name> hibernateFilter< / filter-name>
< filter-class> org.springframework.orm.hibernate4.support.OpenSessionInViewFilter< / filter-class>
< init-param>
< param-name> sessionFactoryBeanName< / param-name>
< param-value> sessionFactory< / param-value>
< / init-param>
< / filter>

< filter-mapping>
< filter-name> hibernateFilter< / filter-name>
< url-pattern> / *< / url-pattern>
< dispatcher> REQUEST< / dispatcher>
< dispatcher> FORWARD< / dispatcher>
< / filter-mapping>

< servlet>
< servlet-name> springapp< / servlet-name>
< servlet-class> org.springframework.web.servlet.DispatcherServlet< / servlet-class>
< init-param>
< param-name> contextConfigLocation< / param-name>
< param-value> /WEB-INF/springapp-servlet.xml< / param-value>
< / init-param>

<加载启动> 1< /加载启动>
< / servlet>



< servlet-mapping>
< servlet-name> springapp< / servlet-name>
< url-pattern> /< / url-pattern>
< / servlet-mapping>


I'm a Spring newbie trying my first app. My hibernate gets closed before the view is rendered and having problems with lazy loaded properties (expected behavior). I've added the OpenSessionInViewFilter to my web.xml and caused the following:

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

Beforehand It was working fine with the default servlet context config I've had (can someone tell me why?). So I've added the following:

 <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/springapp-servlet.xml
    </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

The new error went away..but still getting a no session exception from hibernate

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.model.Store.categories, could not initialize proxy - no Session

I've put a debug message in one of my controllers and it seems that its being initialized 3 times. Maybe I have more than one instance of hibernate session factory bean? My controller methods are marked @Transactional and everything worked until I've attempted to leave the session open to make the lazy fields available for the view.

My full web.xml (with the new context addition, worked fine without it before I've added the hibernate filter):

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > 
    <display-name>
      Spring
    </display-name>
    <description>
     Spring Test
    </description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/springapp-servlet.xml
    </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

   <filter>
      <filter-name>hibernateFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
      <init-param>
         <param-name>sessionFactoryBeanName</param-name>
         <param-value>sessionFactory</param-value>         
      </init-param>      
   </filter>

   <filter-mapping>
     <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
   </filter-mapping> 

  <servlet>
    <servlet-name>springapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>



  <servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <error-page>
    <error-code>500</error-code>
    <location>/error/500</location>
  </error-page>
   <error-page>
    <error-code>404</error-code>
    <location>/resources/pages/error.html</location>
  </error-page>



</web-app>

springapp-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
                    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                    http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                    http://www.springframework.org/schema/context 
                    http://www.springframework.org/schema/context/spring-context-3.2.xsd
                    http://www.springframework.org/schema/tx
                   http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
                   http://www.springframework.org/schema/aop
                   http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    <context:component-scan base-package="com.test.web.controllers,com.test.service.impl" />

    <mvc:annotation-driven />
    <mvc:resources mapping="/resources/**" location="/resources/" /> 

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test?zeroDateTimeBehavior=convertToNull"/>
    <property name="username" value="spring"/>
    <property name="password" value="test"/>
  </bean>

  <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="mappingLocations" value="classpath*:com/test/model/hbm/**/*.hbm.xml" />

    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
        hibernate.show_sql=true
      </value>
    </property>
  </bean>

 <tx:annotation-driven />
  <bean id="transactionManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
  </bean>


    <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/templates/"/>
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
      <property name="cache" value="true"/>
      <property name="prefix" value=""/>
      <property name="suffix" value=".vm"/>
      <property name="layoutUrl" value="index.vm" />

      <!-- if you want to use the Spring Velocity macros, set this property to true -->
      <property name="exposeSpringMacroHelpers" value="true"/>

    </bean>

     <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

        <!-- one of the properties available; the maximum file size in bytes -->
        <property name="maxUploadSize" value="10000000" />
    </bean>

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <bean id="categoryDAO" class="com.test.dao.hibernate.HibernateCategoryDAO">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <bean id="categoryService" class="com.test.service.Categories" scope="singleton">
        <property name="dao" ref="categoryDAO"></property>
    </bean>
    <bean id="storeDAO" class="com.test.dao.hibernate.HibernateStoreDAO">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <bean id="storeService" class="com.test.service.Stores" scope="singleton">
        <property name="dao" ref="storeDAO"></property>
        <property name="categoryDao" ref="categoryDAO"></property>

    </bean>

</beans>

解决方案

My controllers where initialized twice, the same config was used by the root ApplicationContext and by the FrameworkServlet. I've had two contexts initialized. I've created a config for the root context named springapp.xml and moved all my middle tier configuration there and left my web tier configuration in springapp-servlet.xml

My web.xml now looks like this and everything works fine:

      <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/springapp.xml
        </param-value>
        </context-param>

     <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

<filter>
      <filter-name>hibernateFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
      <init-param>
         <param-name>sessionFactoryBeanName</param-name>
         <param-value>sessionFactory</param-value>         
      </init-param>      
   </filter>

   <filter-mapping>
     <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
   </filter-mapping> 

    <servlet>
        <servlet-name>springapp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/springapp-servlet.xml</param-value>
        </init-param>

        <load-on-startup>1</load-on-startup>
      </servlet>



      <servlet-mapping>
        <servlet-name>springapp</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>

这篇关于Spring 3.2 + Hibernate 4 OpenSessionInViewFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆