Chr*_*ris 6 java spring hibernate struts2
我有一个使用Spring设置的Web应用程序来创建我的hibernate会话工厂(单例)和会话和事务(两者都是请求作用域),但它正在以错误的顺序销毁会话和事务.我如何配置它以便在会话之前销毁事务?这是我的spring applicationContext.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="hibernateSessionFactory" scope="singleton"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<!-- The per-http request hibernate session -->
<bean id="hibernateSession" factory-bean="hibernateSessionFactory"
factory-method="openSession" destroy-method="close" scope="request" />
<!-- The per-http request transaction (i need this to be destroyed BEFORE the session) -->
<bean id="hibernateTransaction" factory-bean="hibernateSession"
factory-method="beginTransaction" destroy-method="commit" scope="request" />
</beans>
Run Code Online (Sandbox Code Playgroud)
这是显示在关闭事务之前关闭会话的日志:
16111 [http-8080-3] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy method 'close' on bean with name 'hibernateSession'
16111 [http-8080-3] DEBUG org.hibernate.jdbc.ConnectionManager - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
16111 [http-8080-3] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - trace com.mchange.v2.resourcepool.BasicResourcePool@17e4dee [managed: 4, unused: 3, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@19a8416)
16111 [http-8080-3] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy method 'commit' on bean with name 'hibernateTransaction'
16111 [http-8080-3] DEBUG org.hibernate.transaction.JDBCTransaction - commit
16111 [http-8080-3] WARN org.springframework.beans.factory.support.DisposableBeanAdapter - Invocation of destroy method 'commit' failed on bean with name 'hibernateTransaction'
org.hibernate.SessionException: Session is closed
Run Code Online (Sandbox Code Playgroud)
似乎非单例范围 bean 的 destory 方法调用顺序完全失控。来自文档(5.1.4使用依赖):
bean 定义中的depends-on 属性可以指定初始化时间依赖性,以及(仅在单例 bean 的情况下)相应的销毁时间依赖性
您可以创建一个辅助对象并将 Bean 的创建和销毁委托给它:
public class HelperObject
{
private SessionFactory factory;
private Session session;
private Transaction tx;
public void init()
{
session = factory.createSession();
tx = session.beginTransaction();
}
public void destroy()
{
tx.commit();
session.close();
}
...
}
Run Code Online (Sandbox Code Playgroud)
--
<bean id = "helperObject" class = "HelperObject" scope = "request" init-method = "init" destroy-method = "destroy">
<property name = "factory" ref = "hibernateSessionFactory" />
</bean>
<bean id="hibernateSession" factory-bean="helperObject"
factory-method="getSession" scope="request" />
<bean id="hibernateTransaction" factory-bean="helperObject"
factory-method="getTransaction" scope="request" />
Run Code Online (Sandbox Code Playgroud)
而且,毕竟,也许这不是在 Spring 中管理 Hibernate 会话和事务的最佳方式。考虑使用 Spring 的内置Hibernate和事务支持。
编辑: 嗯,管理交易的正确方法是:
session和transactionbeancreateSession返回的会话工厂org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean。您可以将此会话工厂注入到您的 bean 中,并getCurrentSession在需要会话时调用,它会正常工作。@Transactional事务方法上的注释)。为了使它工作,你应该添加到你的配置中:。
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
<tx:annotation-driven/>
Run Code Online (Sandbox Code Playgroud)