一尘不染

Spring 3.2 + Hibernate 4 OpenSessionInViewFilter

hibernate

我是一名spring新手,正在尝试我的第一个应用程序。我的hibernate状态在呈现视图之前关闭,并且在延迟加载属性(预期行为)方面存在问题。我已将OpenSessionInViewFilter添加到我的web.xml中,并导致以下情况:

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

事先,我在使用默认的servlet上下文配置时效果很好(有人可以告诉我为什么吗?)。因此,我添加了以下内容:

 <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>

新的错误消失了..但是仍然从hibernate中获取无会话异常

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

我在我的一个控制器中放了一条调试消息,似乎它被初始化了3次。也许我有多个hibernate会话工厂bean实例?我的控制器方法已标记为@Transactional,并且一切正常,直到尝试将会话保持打开状态以使惰性字段可用于视图。

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

<?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>

阅读 286

收藏
2020-06-20

共1个答案

一尘不染

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

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

      <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>
2020-06-20