这是关于在服务层使用OpenSessionInViewFilter注释的Spring @Transactional

我对此经历了很多堆栈溢出的帖子,但仍然对我是否应该使用OpenSessionInViewFilter以避免LazyInitializationException感到困惑
如果有人帮助我找出以下查询的答案,那将是非常有帮助的。

  • 在应用程序中使用OpenSessionInViewFilter是不好的做法
    具有复杂的架构。
  • 使用此过滤器可能会导致N+1问题
  • 如果我们使用的是OpenSessionInViewFilter,是否意味着不需要@Transactional

  • 下面是我的Spring配置文件

    <context:component-scan base-package="com.test"/>
    <context:annotation-config/>
     <bean id="messageSource"
            class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
            <property name="basename" value="resources/messages" />
            <property name="defaultEncoding" value="UTF-8" />
        </bean>
     <bean id="propertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
            p:location="/WEB-INF/jdbc.properties" />
     <bean id="dataSource"
            class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
            p:driverClassName="${jdbc.driverClassName}"
            p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
            p:password="${jdbc.password}" />
           <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configLocation">
                <value>classpath:hibernate.cfg.xml</value>
            </property>
            <property name="configurationClass">
                <value>org.hibernate.cfg.AnnotationConfiguration</value>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <!--
                    <prop key="hibernate.hbm2ddl.auto">create</prop>
                     -->
                </props>
            </property>
        </bean>
     <tx:annotation-driven />
     <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
    
      </bean>
    

    最佳答案

    OpenSessionInView是一个servlet筛选器,而不仅仅是打开一个 hibernate session ,并将其存储在服务于请求的线程的SessionHolder中。打开此 session 后,在请求的呈现阶段使用hibernate时,它可以读取Lazy初始化的集合和对象。调用SessionFactory.getCurrentSession()时可以访问此 session 。

    但是,OpenSessionInView只会打开 session ,并且不会开始任何事务。打开 session 后,您可以从数据库中读取对象,但是,如果要在事务中执行某些操作,则需要使用@Transactional批注或其他机制在需要时划定事务的开始和结束位置。

    然后是问题的答案:



    如果您需要避免LazyInitializationException,并且重载只是打开新的Hibernate Session并在每个请求的请求结束时将其关闭,则这是一个好习惯。



    我在许多项目中都使用了此过滤器,并且没有引起任何问题。



    否。您仅在线程的SessionHolder中打开了一个Hibernate Session,但是如果您需要事务,则需要放置@Transactional

    关于java - 带有@Transactional批注的Spring OpenSessionInViewFilter,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23877900/

    10-11 16:25