2011-07-13 118 views
2

我有一個理解@Transactional和@TransactionConfiguration(defaultRollback = true)註解的問題。春季測試事務回滾問題

我有一個測試代碼,它將一個userAccount插入到數據庫中,然後插入另一個同名的帳戶,這會導致DataIntegrityViolationException,因爲AccountName被標記爲Unique。如果@Transactional和@TransactionConfiguration(defaultRollback = true)沒有在TestClass級別進行驗證,這可以正常工作。但是,如果回滾啓用,我不會得到該異常,因爲即使在相同的方法數據不插入到數據庫。如果我在插入第一個帳戶後設置斷點,則數據庫仍爲空。

這裏是我的代碼:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:/spring/applicationContext.xml"}) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
public class DaoTests { 

    @Autowired 
    private Repository repo; 
    @Autowired 
    private AccountService userService; 

    @Before 
    public void orgInstAccount() { 
     Organization o = new Organization(); 
     o.setName("Organisation 1"); 
     repo.saveEntity(o); 

     Institution i1 = new Institution(); 
     i1.setName("xyz"); 
     i1.setOwningOrganization(o); 
     repo.saveEntity(i1); 

    } 

    @Test(expected = DataIntegrityViolationException.class) 
    public void saveUserFail() { 

     Account user = new Account(); 
     user.setAccountname("chz"); 
     user.setPassword(userService.calcMD5Hash("123")); 
     user.setOwningInstitution(repo.getInstitutionByName("xyz")); 
     repo.saveEntity(user); 
     Assert.assertNotNull(repo.getAccountByName("chz")); 


     Account userNew = new Account(); 
     userNew.setAccountname("chz"); 
     userNew.setPassword(userService.calcMD5Hash("123")); 
     userNew.setOwningInstitution(repo.getInstitutionByName("xyz")); 
     repo.saveEntity(userNew); 
     //Here the Exception should be thrown but everything works fine. 

    } 

} 

的倉庫實現是:

@Repository 
@Transactional 
@SuppressWarnings("unchecked") 
public class RepositoryHibernateImpl implements Repository { 

    @Autowired 
    private SessionFactory factory; 

    @Override 
    public void saveEntity(Entity hce) { 
     factory.getCurrentSession().save(hce); 
    } 
} 

也許問題是因爲存儲庫和識別TestClass標有@Transactional?

先謝謝您。

回答

4

呼叫flush()將嘗試立刻改爲SQL調用推遲它,直到事務邊界

factory.getCurrentSession().flush() 
+0

的謝謝你的幫助。這解決了這個問題。但仍然如果我調試沒有什麼實際寫入數據庫,所以一切都在內存數據庫中執行? – drame

+0

如果你真的想知道所有這些工作,我建議你窺視源代碼,特別是SessionFactoryImpl和SessionImpl http://www.docjar.com/html/api/org/hibernate/impl/SessionFactoryImpl.java.html和http://www.docjar.com/html/api/org/hibernate/impl/SessionImpl.java.html –