这与Spring 在服务层上OpenSessionInViewFilter
使用 @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会话,并将其存储在SessionHolder
服务请求的线程中。打开此会话后,在请求的呈现阶段使用hibernate时,它可以读取Lazy初始化的集合和对象。调用时可以访问此会话SessionFactory.getCurrentSession()
。
但是,OpenSessionInView只会打开会话,并且不会开始任何事务。在打开会话的情况下,您可以从数据库中读取对象,但是,如果要在事务中执行某些操作,则需要@Transactional
注释或其他机制来在需要时划定事务的开始和结束位置。
然后是问题的答案:
在具有复杂模式的应用程序中使用OpenSessionInViewFilter是不好的做法。
如果您需要避免LazyInitializationException并且重载只是打开新的Hibernate
Session并在每个请求的请求结束时将其关闭,则这是一个好习惯。
使用此滤镜可能会导致N + 1问题
我在许多项目中都使用了此过滤器,并且不会引起任何问题。
如果我们使用的是OpenSessionInViewFilter,是否意味着不需要@Transactional?
不会。您只能在线程的SessionHolder中打开一个Hibernate Session,但是如果需要Transaction,则需要put
@Transactional
。
问题内容: 我正在阅读使用Spring框架进行的事务管理。在第一个组合中,我使用了Spring + hiberante,并使用了Hibernate的API来控制事务(Hibenate API)。接下来,我想使用注释进行测试,它确实起作用。 我对此感到困惑: JPA,JTA,Hibernate是否具有它们自己的事务管理方式。例如,考虑如果我使用Spring + Hibernate,在那种情况下您会使
问题内容: 我正在使用Spring注释来管理我的事务,如下所示: 我想知道如果忘记注释会发生什么: 当alertDAO实现如下时: 似乎Hibernate允许我从数据库中获取数据,即使没有注释也是如此。 这种粗心大意的后果是什么?可能发生的最坏情况是什么? 问题答案: 根据文档(Spring docs ),它仅仅是元数据,它表明方法或接口可以由“具有交易意识的”事物(例如)进行配置。 相信只有 t
问题内容: 我知道从同一个类内部调用事务方法时,它不会在事务中运行。Spring为事务方法创建代理,并将它们包装在try- catch块中,如果发生异常,则回滚。请考虑以下情形: 假设已从另一个对象调用,并且中发生了异常,因此成功完成但未成功。据我所知,尽管并且不是事务性的(因为它们是从同一个对象中调用的),但由于它是事务性的,因此仍应回滚。 我不明白的是,为什么人们说自我调用会破坏交易?只要调用
问题内容: 美好的一天。如下代码: 据我了解,如果方法中存在异常,则不会回滚事务。以及如何使它滚动?并返回SomeResult 问题答案: 您不应该以编程方式调用回滚。根据docs的建议,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。 在你的情况下,像这样 看一下@Transaction API 和有关回滚事务的文档。 如果尽管有文档建议,但仍要进行程序化回滚,则需要按照已建议的
问题内容: 我有许多带有JAXB批注的实体,我想使用消息转换器将其转换为JSON。 我知道读取JAXB批注的ObjectMapper可以工作: 但是当我打电话给我的休息服务时,默认注册的MappingJacksonHttpMessageConverter(未配置为读取JAXB)似乎接管了- 由于@XmlTransient被忽略时由于循环引用而导致堆栈溢出… 如何配置Spring以使用Mapping
在spring boot annotate中使用@Transactional从控制器调用update(),此update()调用update2()。所以,当我尝试使用update2()将重复值保存到数据库中时,它不会向update()抛出异常,而是转到控制器方法。我想在update()中处理异常。