使用@Transactional注释Spring OpenSessionInViewFilter [英] Spring OpenSessionInViewFilter with @Transactional annotation

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

问题描述

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



我经历了这么多的堆栈溢出后,但仍然困惑我是否应该使用 OpenSessionInViewFilter 或不要避免 LazyInitializationException
如果有人帮助我找到对以下查询的答案,那将会非常有帮助。


  • 在具有复杂模式的应用程序
    中使用 OpenSessionInViewFilter 是不好的做法。
  • 使用此过滤器的
  • 可能会导致<$ c $如果我们使用 OpenSessionInViewFilter ,它是否表示问题

  • > @Transactional 不需要?



以下是我的Spring配置文件

 < context:component-scan base-package =com.test/> 
< context:annotation-config />
< bean id =messageSource
class =org.springframework.context.support.ReloadableResourceBundleMessageSource>
< property name =basenamevalue =resources / messages/>
< property name =defaultEncodingvalue =UTF-8/>
< / bean>
class =org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
p:location =/ WEB-INF / jdbc.properties/> ;
< bean id =dataSource
class =org.apache.commons.dbcp.BasicDataSourcedestroy-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 =dataSourceref =dataSource/>
< property name =configLocation>
< value> classpath:hibernate.cfg.xml< / value>
< / property>
< property name =configurationClass>
< value> org.hibernate.cfg.AnnotationConfiguration< / value>
< / property>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> $ {jdbc.dialect}< / prop>
< prop key =hibernate.show_sql> true< / prop>
<! -
< prop key =hibernate.hbm2ddl.auto> create< / prop>
- >
< /道具>
< / property>
< / bean>
< tx:annotation-driven />
< bean id =transactionManager
class =org.springframework.orm.hibernate3.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>

< / bean>


解决方案

OpenSessionInView 是一个servlet过滤器,而不仅仅是打开一个hibernate会话并将它存储在为请求提供服务的线程的 SessionHolder 中。在这个会话打开的时候,当你在请求的呈现阶段使用这个会话时,hibernate可以读取Lazy初始化的集合和对象。当您调用 SessionFactory.getCurrentSession()时,可以访问此会话。然而,OpenSessionInView只是打开会话并它不会开始任何交易。打开会话可以从数据库中读取对象,但是如果您想在事务中执行某些操作,您需要使用 @Transactional 注释或其他机制来标定开始和结束当你想要的交易。



然后问题的答案:

lockquote

在具有复杂模式的应用程序中使用OpenSessionInViewFilter是不好的做法。


如果您需要避免LazyInitializationException和过载只是打开新的Hibernate Session并在每个请求的请求结束时关闭它。


使用此过滤器可能导致N + 1问题


$ b $如果我们使用的是OpenSessionInViewFilter,那么它表示@Transactional不是必填?


没有。你只在线程的SessionHolder中打开一个Hibernate Session,但是如果你需要Transaction,你需要把 @Transactional


This is regarding Spring OpenSessionInViewFilter using with @Transactional annotation at service layer.

i went through so many stack overflow post on this but still confused about whether i should use OpenSessionInViewFilter or not to avoid LazyInitializationException It would be great help if somebody help me find out answer to below queries.

  • Is it bad practice to use OpenSessionInViewFilter in application having complex schema.
  • using this filter can cause N+1 problem
  • if we are using OpenSessionInViewFilter does it mean @Transactional not required?

Below is my Spring config file

<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 is a servlet filter than just Open a hibernate session and store it in the SessionHolder for the thread that is serving the request. With this session opened, hibernate can read the Lazy initialized collections and objects when you use this in the rendering stage of the request. This session can be accessed when you invoke SessionFactory.getCurrentSession().

But, OpenSessionInView just opens the session and it doesn't begin any transactions. With a session opened you can read objects from database but, if you want to do something in a transaction you need @Transactional annotations or other mechanism to demarcate the begin and the end of the transaction when you want.

Then the answer of the questions:

Is it bad practice to use OpenSessionInViewFilter in application having complex schema.

This is a good practice if you need avoid the LazyInitializationException and the overload is just open new Hibernate Session and close it at the end of the request for each request.

Using this filter can cause N+1 problem

I use this filter in many projects and not cause any problem.

if we are using OpenSessionInViewFilter does it mean @Transactional not required?

No. You only have a Hibernate Session opened in the SessionHolder of the thread, but if you need Transactions you need put @Transactional.

这篇关于使用@Transactional注释Spring OpenSessionInViewFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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