下面的测试是在我的应用程序中使用Hibernate3。当我将它升级到hibernate4时,它开始失败。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(inheritLocations=false,locations={
"/hibernate/spring-SF-tests.xml",
"/hibernate/spring-transaction.xml",
"/hibernate/testBeans.xml"
,"/hibernate/spring-audit.xml",
"/hibernate/iwrs-mail-beans-test.xml",
"/hibernate/fake-audit-meaning.xml"
})
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
public class CodeAuditIntegrationTest extends CodeIntegrationTest {
@Autowired
private SessionFactory auditFactory;
@Before
public void cleanAudit(){
auditFactory.getCurrentSession().createQuery("delete from AuditLogRecord").executeUpdate();
}
@Test
public void clinicalTrialAssociationTest() {
super.clinicalTrialAssociationTest();
}
}
失败的是:
org.hibernate.HibernateException:找不到当前线程的会话 在 org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 在 org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881)
我的应用程序中有2个不同的会话工厂:sessionFactory和auditFactory。两者都在spring中配置(参见[1])。
问题是在hibernate4配置中删除了属性exposeTransactionAwareSessionFactory 。我的auditFactory设置为true。我相信删除此属性会使注入的auditFactory无法在事务中获取会话(因为txManger是为sessionFactory配置的),因此会产生错误。
问题:
我看到的唯一选择是将所有使用auditFactory的代码包装在使用@Transactional(otherTxManager)注释的Helper类中。我确实试过了,但我还有其他一些问题:
[1]相关XML配置:
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="sessionFactory" scope="singleton"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2dll}</prop>
<prop key="hibernate.hbm2ddl.import_files">${hibernate.sql_scripts}</prop>
</props>
</property>
<property name="packagesToScan">...</property>
<property name="annotatedPackages">...</property>
<property name="mappingLocations">...</property>
<property name="dataSource" ref="c3p0DataSource" />
<property name="entityInterceptor" ref="auditInterceptor" />
</bean>
<bean id="auditFactory" scope="singleton"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="exposeTransactionAwareSessionFactory"> -->needs to be removed in hibernate4!
<value>true</value>
</property>
<property name="mappingLocations">...</property>
<property name="packagesToScan">...</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2dll}</prop>
</props>
</property>
<property name="dataSource" ref="c3p0DataSource" />
</bean>
[2]两家工厂使用相同的dataSource时出现问题:
org.springframework.transaction.IllegalTransactionStateException:找到预绑定的JDBC连接!如果告知要管理DataSource本身,HibernateTransactionManager不支持在DataSourceTransactionManager中运行。无论是Hibernate还是JDBC访问,建议对单个DataSource上的所有事务使用单个HibernateTransactionManager。 在org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:329)
[3]由于宣布2名交易经理而导致黄瓜测试出现问题:
org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义类型为[org.springframework.transaction.PlatformTransactionManager]的唯一bean:期望的单个bean但找到2:txAudit,txManager