Dan*_*ack 2 session spring annotations hibernate
我'继承了'一个使用Spring注释来管理Hibernate的事务/会话的项目.或者至少它意味着.目前,Hibernate会话永远不会被刷新(它们被设置为FLUSH_MODE_NEVER),并且需要手动刷新DAO以便将任何数据写入数据库.
此外,所有DTO对象都驻留在hibernate的内存中,最终导致OutOfMemory错误.
我相信我需要告诉Spring/Hibernate关闭会话或提交事务.在我的控制器类中,我有一个用于处理请求的带注释的方法:
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
...
}
Run Code Online (Sandbox Code Playgroud)
在applicationContetxt.xml文件中,我相信我设置了hibernate事务管理器并告诉spring使用注释:
<!-- hibernate3 transaction manager -->
<bean id="transactionManagerLocal" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource" ref="${local.data.source}" />
<property name="sessionFactory" ref="localSessionFactory" />
</bean>
<!-- Demarcate using @Transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManagerLocal" order="200" />
Run Code Online (Sandbox Code Playgroud)
我不仅非常确定配置是错误的,因为数据没有写入数据库而没有手动调用每个DAO上的flush,从日志文件我们可以看到事务管理器已经刷新并且会话关闭被禁用:
INFO [http-8080-2] TransactionFactoryFactory - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO [http-8080-2] TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO [http-8080-2] SettingsFactory - Automatic flush during beforeCompletion(): disabled
INFO [http-8080-2] SettingsFactory - Automatic session close at end of transaction: disabled
Run Code Online (Sandbox Code Playgroud)
需要做些什么才能使Spring/hibernate自动刷新DAO和/或关闭会话以防止Hibernate使用大量内存?
欢呼丹
<!-- MySQL/InnoDB session factory -->
<bean id="localSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="${local.data.source}"/>
<property name="mappingResources">
<list>
<value>net/company/projectname/domain/ExchangeRate.hbm.xml</value>
<!-- Other -->
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.connection.zeroDateTimeBehavior">convertToNull</prop>
<!--
DOES NOTHING
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
-->
</props>
</property>
</bean>
<!-- hibernate3 transaction manager -->
<bean id="transactionManagerLocal" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource" ref="${local.data.source}" />
<property name="sessionFactory" ref="localSessionFactory" />
</bean>
<!-- Demarcate using @Transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManagerLocal" order="200" />
<bean id="exchangeRateDAO" class="net.company.project.dao.hibernate.impl.ExchangeRateDAOImpl">
<property name="sessionFactory" ref="localSessionFactory"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
我的一位聪明的同事发现了问题所在.
实际问题是,您声明为@Transactional的方法是从基类调用的继承方法,这意味着Spring无法拦截对方法的调用并将其包装在事务中.
Spring将事务管理实现为方面,而方面则通过代理实现.这种情况的局限性在于,如果一个对象自身调用一个方法(这是因为继承而发生的事情),那么代理就不会看到调用(因为它发生在类内部,就像调用私有方法一样),以及不能这么做.
这是有道理的,但似乎非常危险,因为它没有任何错误消息或警告就无法写入任何数据.
| 归档时间: |
|
| 查看次数: |
12929 次 |
| 最近记录: |