2

下面的测试在我的 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.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881) 的 org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 中找不到当前线程的会话

我的应用程序中有 2 个不同的会话工厂:sessionFactory 和 auditFactory。两者都在 spring 中配置(参见 [1])。

问题是在 hibernate4 配置中,属性exposeTransactionAwareSessionFactory 被删除了。我为我的auditFactory 设置为true。我相信删除此属性会使注入的 auditFactory 无法在事务中获取会话(因为 txManger 是为 sessionFactory 配置的),因此会产生错误。

问题:

  1. 我怎样才能让 auditFactory 在这个测试中拥有由 spring 管理的事务?
  2. 这是hibernate 3中的exposeTransactionAwareSessionFactory属性发生的事情吗?

我看到的唯一替代方法是将所有使用 auditFactory 的代码包装在一个用 @Transactional(otherTxManager) 注释的 Helper 类中。我确实尝试过,但在那里我遇到了一些额外的问题:

  1. 我需要使用一个单独的数据源(否则我会得到 [2])
  2. 使用 2 个单独的数据源,我会在 Cucumber 测试中遇到类似的错误,现在与 transactionManager [3] 相关

[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] 两个工厂使用相同数据源的问题:

org.springframework.transaction.IllegalTransactionStateException:找到预绑定的 JDBC 连接!如果被告知要管理 DataSource 本身,HibernateTransactionManager 不支持在 DataSourceTransactionManager 中运行。建议对单个 DataSource 上的所有事务使用单个 HibernateTransactionManager,无论是 Hibernate 还是 JDBC 访问。在 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

4

0 回答 0