精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-25
netfly 写道 daquan198163 写道 并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的 怎么回滚?我怎么回滚都不起作用,做插入操作的时候,总是把数据写入了数据库中。 你的ut不是已经扩展自AbstractTransactionalDataSourceSpringContextTests了吗,只要你不调用super.setDefaultRollback(false);这个基类默认就会回滚的呀! 于是由此产生hibernate偷懒,无法发现数据库操作错误的问题了,然后我们建议你在测试中显示调用session.flush 或者参杂一些查询调用(其实也是为了触发session.flush) |
|
返回顶楼 | |
发表时间:2006-12-25
不过这里面也有些陷阱:如果你的测试还是会把数据写入了数据库的话,可能是由于你加载的spring配置文件里有多个事务管理器或session工厂,从而导致AbstractTransactionalDataSourceSpringContextTests没有获得正确的TransactionManager或SessionFactory,所以就没能回滚
不过这种错误也不太容易犯,因为AbstractTransactionalDataSourceSpringContextTests默认按类型组装,如果她发现有多个TransactionManager类型的bean是要报错的,此时你需要调用setAutowireMode(this.AUTOWIRE_BY_NAME);使其按名称组装 |
|
返回顶楼 | |
发表时间:2006-12-25
我的代码,
先自己实现了一个容器,用自己的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; } } |
|
返回顶楼 | |
发表时间: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的处理。 |
|
返回顶楼 | |
发表时间:2006-12-27
问题解决了,原来是我的数据库不支持事务,哈哈!谢谢大家的关注,springside误导了我,害人不浅呀。
MYSQL中只有INNODB和BDB类型的数据表才支持事务处理!其他的类型是不支持. |
|
返回顶楼 | |
发表时间:2007-04-12
加一个拦截器,在方法结束后调用flush操作
|
|
返回顶楼 | |