论坛首页 Java企业应用论坛

AbstractTransactionalDataSourceSpringContextTests=鸡肋?

浏览 11890 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-12-25  
netfly 写道
daquan198163 写道
并且在测试结束后也可以回滚,免得污染DB
当然,像你那样在tearDown里面显式的flush也应该可以的


怎么回滚?我怎么回滚都不起作用,做插入操作的时候,总是把数据写入了数据库中。

你的ut不是已经扩展自AbstractTransactionalDataSourceSpringContextTests了吗,只要你不调用super.setDefaultRollback(false);这个基类默认就会回滚的呀!
于是由此产生hibernate偷懒,无法发现数据库操作错误的问题了,然后我们建议你在测试中显示调用session.flush
或者参杂一些查询调用(其实也是为了触发session.flush)
0 请登录后投票
   发表时间:2006-12-25  
不过这里面也有些陷阱:如果你的测试还是会把数据写入了数据库的话,可能是由于你加载的spring配置文件里有多个事务管理器或session工厂,从而导致AbstractTransactionalDataSourceSpringContextTests没有获得正确的TransactionManager或SessionFactory,所以就没能回滚
不过这种错误也不太容易犯,因为AbstractTransactionalDataSourceSpringContextTests默认按类型组装,如果她发现有多个TransactionManager类型的bean是要报错的,此时你需要调用setAutowireMode(this.AUTOWIRE_BY_NAME);使其按名称组装
0 请登录后投票
   发表时间: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;
	}
}
0 请登录后投票
   发表时间: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的处理。
0 请登录后投票
   发表时间:2006-12-27  
问题解决了,原来是我的数据库不支持事务,哈哈!谢谢大家的关注,springside误导了我,害人不浅呀。

MYSQL中只有INNODB和BDB类型的数据表才支持事务处理!其他的类型是不支持.
0 请登录后投票
   发表时间:2007-04-12  
加一个拦截器,在方法结束后调用flush操作
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics