我们在项目中使用spring + hibernate + jsf + mysql + atomikos。下面是版本细节:
当我使用JSF2 ViewScope bean在服务层中使用事务服务时,它适用于第一个请求。它在出现问题时回滚,并在没有问题时将两个实体保存到不同的表中。但是,如果我在同一个视图上执行第二个请求,那么如果我在DAO中调用getSessionFactory()
,则会得到null对象。
对此有何帮助?
以下是我的设置等:
@ManagedBean
@ViewScoped
public class TestPageBean {
public String click(){
testService.saveTest(obj1, obj2);
}
}
@Transactional
public class TestService {
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void saveTest(Object1 obj1, Object2 obj2) {
dao1.save(obj1);
dao2.save(obj2);
}
}
GenericDao包含保存方法:
public void save(Entity entity){
Session session = getSessionFactory().getCurrentSession().save(entity);
}
这是Spring的xml配置:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="atomikosDataSourceBean" />
</property>
<property name="packagesToScan">
<list>
<value>com.company.txtest.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
</props>
</property>
</bean>
<bean id="atomikosDataSourceBean" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName"><value>NonXADBMS</value></property>
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/txtestdb?autoReconnect=true</value></property>
<property name="user"><value>username</value></property>
<property name="password"><value>password</value></property>
<property name="minPoolSize"><value>1</value></property>
</bean>
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown"><value>true</value></property>
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout"><value>300</value></property>
</bean>
<tx:annotation-driven/>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager"><ref bean="atomikosTransactionManager" /></property>
<property name="userTransaction"><ref bean="atomikosUserTransaction" /></property>
</bean>
<bean id="genericDaoHibernate" class="com.company.txtest.dao.hibernate.GenericDaoHibernate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>