我正在使用Spring并遵循junit-method:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:TestProject-spring-test.xml" })
@Transactional
public abstract class BaseTest {
[...]
@Test
public void testSaveLoadedObject() {
SubTestModel st = modelService.load(subTestPk);
st.setSimpleObject("testString");
modelService.save(st);
//now reload the object to ensure that everything has been saved correctly
st = modelService.load(st.getId());
s+= "\n#3 afterLoad: " + st.getSimpleObject();
//fails:
Assert.assertTrue(st.getSimpleObject().equals("testString"));
}
}
ModelService-方法:
@Autowired
private JdbcTemplate db;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void save(final ItemModel model, String newValue) {
db.update("UPDATE table SET column=? WHERE id=?", new Object[] { newValue, model.getId() });
}
@Override
public <T extends AbstractItemModel> T load(final int id) {
...
DAO.loadValue(...)
}
DAO-方法: @Autowired private JdbcTemplate db;
@Override
public <T> T loadValue(final AbstractItemModel model, final String columnName) {
final String sql = "SELECT column FROM table WHERE id=" + model.getId();
Object plain = db.queryForObject(sql, new RowMapper<Object>() {
@Override
public Object mapRow(ResultSet r, int rowNum) throws SQLException {
return r.getObject(columnName);
}
});
return plain;
}
发生以下情况:
新值存储在数据库中(在mysql中设置“SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED”时可见)。
getSimpleObject-DB in DB =“testString”
*但是当调用load方法时,它会获得“old”(=保存前的值)值*
调试器中的getSimpleObject-Value =“simpleObjectValue”
为什么加载方法无法读取最近保存的值(在同一个事务和方法中)?
您看到它不会创建新事务。甚至在整个测试方法中使用“@Transaction(isolation = READ_UNCOMMITTED)”设置隔离级别也无济于事
任何人都可以解开这个谜团吗?
提前致谢!
答案 0 :(得分:0)
在save方法上将传播更改为REQUIRES_NEW(在数据库上提交更改并打开新事务)。
或者甚至更好,在保存测试后添加flush调用(这样做更好,因为您不会更改代码只是为了使其适应您的集成测试)。