2006-12-23
AbstractTransactionalDataSourceSpringContextTests=鸡肋?
关键字: spring hibernate test
我用mysql做数据库,使用AbstractTransactionalDataSourceSpringContextTests测试时,发现根本没有写数据库,连错误都没有发生,直到我提交了事务才写数据库,并发现了错误。
springside的高人也说过:hibernate太奸诈了,如果全部默认回滚,只会在session里干活,一点不写数据库,达不到完全的测试效果。
http://www.springside.org.cn/docs/reference/UnitTest.htm
如果是这样的话,是否可以认为,AbstractTransactionalDataSourceSpringContextTests对hibernate来说,是个完全的鸡肋?因为不提交的话,事务完全回滚,根本不写数据库,连错误都找不出;提交的话,又破坏了数据。
如果不是鸡肋,那该如何改进?
springside的高人也说过:hibernate太奸诈了,如果全部默认回滚,只会在session里干活,一点不写数据库,达不到完全的测试效果。
http://www.springside.org.cn/docs/reference/UnitTest.htm
如果是这样的话,是否可以认为,AbstractTransactionalDataSourceSpringContextTests对hibernate来说,是个完全的鸡肋?因为不提交的话,事务完全回滚,根本不写数据库,连错误都找不出;提交的话,又破坏了数据。
如果不是鸡肋,那该如何改进?
评论
littcai
2007-04-12
加一个拦截器,在方法结束后调用flush操作
netfly
2006-12-27
问题解决了,原来是我的数据库不支持事务,哈哈!谢谢大家的关注,springside误导了我,害人不浅呀。
MYSQL中只有INNODB和BDB类型的数据表才支持事务处理!其他的类型是不支持.
MYSQL中只有INNODB和BDB类型的数据表才支持事务处理!其他的类型是不支持.
Godlikeme
2006-12-26
protected ConfigurableApplicationContext loadContext(Object key) throws Exception {
setAutowireMode(AUTOWIRE_BY_NAME);
setDefaultRollback(false);
return (ConfigurableApplicationContext) ContainerFactory.newInstance((String) key, getResources());
}
这个太明显了吧,还是setDefaultRollback(false)呢。
没有看到在任何地方做session的处理。
setAutowireMode(AUTOWIRE_BY_NAME);
setDefaultRollback(false);
return (ConfigurableApplicationContext) ContainerFactory.newInstance((String) key, getResources());
}
这个太明显了吧,还是setDefaultRollback(false)呢。
没有看到在任何地方做session的处理。
netfly
2006-12-25
我的代码,
先自己实现了一个容器,用自己的ContainerFactory来生成这个容器,再加入到SpringContext中去,代码如下:
然后再继承这个抽象类,代码如下:
先自己实现了一个容器,用自己的ContainerFactory来生成这个容器,再加入到SpringContext中去,代码如下:
public abstract class AbstractDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests {
/**
* 不同的应用程序必须指定不同的key值,也就是说不同的应用程序必须覆盖此方法
*/
@Override
protected Object contextKey() {
return Constants.FAMEWORK_CONTAINER_KEY;
}
@Override
protected ConfigurableApplicationContext loadContext(Object key) throws Exception {
setAutowireMode(AUTOWIRE_BY_NAME);
setDefaultRollback(false);
return (ConfigurableApplicationContext) ContainerFactory.newInstance((String) key, getResources());
}
/**
* get resources
* 可以被子类覆盖
* @return String[]
*/
protected String[] getResources() {
return new String[] {
"classpath:framework/framework-persistence-hibernate.xml",
"classpath:biz/biz-bookstore.xml" };
}
}
然后再继承这个抽象类,代码如下:
public class CustomerDAOTest extends AbstractDaoTestCase {
private CustomerDAO customerDAO;
public void testCRUD() {
Customer customer = new Customer();
// customer.setId(1);
customer.setLoginid("netfly");
customer.setName("netfly");
customer.setPasswd("1234");
customer.setEmail("oo@oo.com");
customer.setAddress("shanghai");
customer.setStatus("1");
//保存对象,这里总会把数据插入数据库
customerDAO.save(customer);
// // 保证id生成
assertNotNull(customer.getId());
//
// //重新获得对象
customer = customerDAO.get(customer.getId());
//保证能获取刚才保存的对象
assertNotNull(customer);
// 保证获取对象的属性值与保存时相同
assertEquals("oo@oo.com", customer.getEmail());
// // 删除对象
// customerDAO.remove(customer);
// try {
// customerDAO.get(customer.getId());
// fail("Entity found in database after deleted");
// } catch (Exception e) {
// assertNotNull(e.getMessage());
// }
//这里回滚没有任何效果
// transactionManager.rollback(transactionStatus);
}
/**
* @param customerDAO the customerDAO to set
*/
public void setCustomerDAO(CustomerDAO customerDAO) {
this.customerDAO = customerDAO;
}
}
daquan198163
2006-12-25
不过这里面也有些陷阱:如果你的测试还是会把数据写入了数据库的话,可能是由于你加载的spring配置文件里有多个事务管理器或session工厂,从而导致AbstractTransactionalDataSourceSpringContextTests没有获得正确的TransactionManager或SessionFactory,所以就没能回滚
不过这种错误也不太容易犯,因为AbstractTransactionalDataSourceSpringContextTests默认按类型组装,如果她发现有多个TransactionManager类型的bean是要报错的,此时你需要调用setAutowireMode(this.AUTOWIRE_BY_NAME);使其按名称组装
不过这种错误也不太容易犯,因为AbstractTransactionalDataSourceSpringContextTests默认按类型组装,如果她发现有多个TransactionManager类型的bean是要报错的,此时你需要调用setAutowireMode(this.AUTOWIRE_BY_NAME);使其按名称组装
daquan198163
2006-12-25
netfly 写道
daquan198163 写道
并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的
当然,像你那样在tearDown里面显式的flush也应该可以的
怎么回滚?我怎么回滚都不起作用,做插入操作的时候,总是把数据写入了数据库中。
你的ut不是已经扩展自AbstractTransactionalDataSourceSpringContextTests了吗,只要你不调用super.setDefaultRollback(false);这个基类默认就会回滚的呀!
于是由此产生hibernate偷懒,无法发现数据库操作错误的问题了,然后我们建议你在测试中显示调用session.flush
或者参杂一些查询调用(其实也是为了触发session.flush)
Godlikeme
2006-12-25
netfly 写道
daquan198163 写道
并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的
当然,像你那样在tearDown里面显式的flush也应该可以的
怎么回滚?我怎么回滚都不起作用,做插入操作的时候,总是把数据写入了数据库中。
netfly
2006-12-25
daquan198163 写道
并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的
当然,像你那样在tearDown里面显式的flush也应该可以的
怎么回滚?我怎么回滚都不起作用,做插入操作的时候,总是把数据写入了数据库中。
daquan198163
2006-12-25
Godlikeme 写道
daquan198163 写道
ecsun 写道
super.setDefaultRollBack(false)
请先看清楚问题
对呀,这样不就可以防止hibernate不干活了么?并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的
Godlikeme
2006-12-24
daquan198163 写道
ecsun 写道
super.setDefaultRollBack(false)
请先看清楚问题
daquan198163
2006-12-24
ecsun 写道
super.setDefaultRollBack(false)
请先看清楚问题
daquan198163
2006-12-24
好象遇到过类似问题,发现在调用一些查询方法后,之前还正常的一些测试会报错,当时觉得很奇怪。
楼主你试试在代码中掺杂一些无关紧要的查询方法调用,估计hibernate怕你读出脏数据就会执行写入操作了
楼主你试试在代码中掺杂一些无关紧要的查询方法调用,估计hibernate怕你读出脏数据就会执行写入操作了
netfly
2006-12-24
用super.setDefaultRollBack(false)我试过,弄脏了数据。
Godlikeme的方法我再尝试一下,多谢各位的帮助。
Godlikeme的方法我再尝试一下,多谢各位的帮助。
Godlikeme
2006-12-24
这个问题的关键在于,AbstractTransactionalDataSourceSpringContextTests缺乏对hibernate session的处理,需要对其进行扩展,
不知道测试代码是怎么写的,只是很奇怪没有session支持,测试怎么跑的起来。
扩展基本思路是在事务开始后,结束前把测试方法包装在
HibernateTemaplate.executeWithSession(...){
public Object doInHibernate(Session session) {
runTest();
session.flush();//synchornize database, errors will be reported.
session.clear();}...}
这样在事务提交或回滚前,错误会报出来。
不知道测试代码是怎么写的,只是很奇怪没有session支持,测试怎么跑的起来。
扩展基本思路是在事务开始后,结束前把测试方法包装在
HibernateTemaplate.executeWithSession(...){
public Object doInHibernate(Session session) {
runTest();
session.flush();//synchornize database, errors will be reported.
session.clear();}...}
这样在事务提交或回滚前,错误会报出来。
Godlikeme
2006-12-24
不好意思,刚才问题没想清楚,代我再想想发出来。
ecsun
2006-12-24
super.setDefaultRollBack(false)
- 浏览: 61257 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
链接
最新评论
-
让Eclipse拖着myeclipse ...
不錯,Eclipse3.3會好很多
-- by wenson -
Yale CAS最佳实践 --全部
引用能否再介绍一下这种解决方案呢 修改edu.yale.its.tp.cas. ...
-- by netfly -
Yale CAS最佳实践 --全部
太复杂了,看不明白!
-- by Arden -
Yale CAS最佳实践 --全部
netfly 写道呵呵,最近从网上查到一点资料,完全不必要再改C:\WINDOW ...
-- by juliashine -
Yale CAS最佳实践 --全部
哈哈,本人欢迎任何朋友转载,只要保留出处就行。
-- by netfly






评论排行榜