gpt4 book ai didi

java - 将 AbstractTransactionalDataSourceSpringContextTests 与 Hibernate 和 DbUnit 一起使用 - 找不到插入的数据

转载 作者:行者123 更新时间:2023-12-02 08:31:54 25 4
gpt4 key购买 nike

所有, 我正在尝试为使用 Hibernate 的 Dao 编写单元测试。我也在使用 Spring,因此我尝试扩展 AbstractTransactionalDataSourceSpringContextTests,并在 onSetUpInTransaction 方法中的每个测试之前使用 DBUnit 将数据插入数据库。

从我的日志中,我可以看到 DbUnit 能够成功地将数据插入 onSetUpInTransaction 中。但是,当我运行使用 Dao(因此使用 Hibernate)的测试方法来尝试访问该数据 (testGetPersonById2) 时,找不到数据,即使所有这些应该发生在同一笔交易。测试方法完成运行(失败)后,我从 AbstractTransactionalDataSourceSpringContextTests 中看到日志语句,表明事务确实已正确回滚。

看起来 onSetUpInTransaction 和 Hibernate session 必须使用不同的事务,但我不明白为什么。有人有这样的例子吗?关于我缺少什么的建议?

这是我到目前为止所得到的:

public class PersonDaoTest extends AbstractTransactionalDataSourceSpringContextTests{

private Log logger = LogFactory.getLog(PersonDaoTest.class);

private PersonDaoImpl personDao;

@Override
public void onSetUpInTransaction() throws Exception {
// Load test data using DBUnit
super.onSetUpBeforeTransaction();
DataSource ds = jdbcTemplate.getDataSource()
Connection con = DataSourceUtils.getConnection(ds);
IDatabaseConnection dbUnitCon = new DatabaseConnection(con);
DatabaseConfig config = dbUnitCon.getConfig();
config.setFeature("http://www.dbunit.org/features/qualifiedTableNames",
true);

//This dataset contains a single entry in the Persons table,
// a new person with Id = 998877665, it gets inserted successfully
IDataSet dataSet = new FlatXmlDataSet(new FileInputStream(
"./PersonDaoTest.xml"));
logger.warn("dataSet = " + dataSet);
try {
DatabaseOperation.REFRESH.execute(dbUnitCon, dataSet);
SessionFactoryUtils.getSession(getSessionFactory(), false).flush();

} finally {
DataSourceUtils.releaseConnection(con, ds);
}

}

//This test PASSES, because the Person with Id = 9 already
//exists in the database, it does not rely on the data being set up in the
// onSetUpInTransaction method
@Test
public void testGetPersonById() {

Person person = personDao.findById(9L);
assertNotNull("person should not be null", person);

}

//This test FAILS at the assertNotNull line, because
//no Person with Id = 998877665 exists in the database,
//even though that Person was inserted
//in the onSetUpInTransaction method - it seems
//that hibernate cannot see that insertion.
@Test
public void testGetPersonById2() {

Person person = personDao.findById(998877665L);
assertNotNull("person should not be null", person);

}

更新:这是我的 spring 配置:

<bean id="propertyConfigurer"       class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>

<bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">
<constructor-arg>
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
</constructor-arg>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>


<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref bean="dataSource"/></property>

<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>

<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.query_cache_factory">org.hibernate.cache.StandardQueryCacheFactory</prop>
</props>
</property>
</bean>

<!-- The Hibernate interceptor
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>-->

<bean id="personDao" class="my.dao.PersonDaoImpl">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>

最佳答案

我花了更多的时间来解决这个问题,但在尝试使用 onSetUpInTransaction 方法时却找不到任何有效的方法。我最终转而使用 onSetUpBeforeTransaction 和 onTearDownAfterTransaction 。这并不完全理想,因为 onSetUpBeforeTransaction 方法最终会将其数据插入提交到数据库,然后必须在 onTearDownAfterTransaction 中清除该数据。但是,测试本身仍然可以根据需要插入和更新数据,并将这些更改全部回滚,因为每个测试仍然在其自己的事务中运行。因此,当测试插入新数据时,我不需要做任何特殊的清理工作,这意味着我无论如何都实现了我的目标之一!

关于java - 将 AbstractTransactionalDataSourceSpringContextTests 与 Hibernate 和 DbUnit 一起使用 - 找不到插入的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3137588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com