I have one jUnit test where I test if my Entity - a Musician must have unique name and I am checking if it is declined by the DB as intended. I have decided to manage my transactions in Spring manually to better understand what is going on and not to use @Transactional approach. I have read in the documentation of the rollback() method of PlatformTransactionManager that when the commit() throws an error, I must not perform rollback() on txManager because the commit() has already rolled back this transaction. Link on it is here. But when I don't call this rollback() method, DB goes into illegal state and whole schema is corrupted and tests halt. When I add one IF to make sure tx is not completed and one call of rollback() method, everything is ok. Here is the code:
@Test
public void testAddMusicianWithNotUniqueName() throws Exception {
System.out.println("addMusicianWithNotUniqueName");
Musician musician1 = new Musician();
musician1.setName("Musician 1");
Musician musician2 = new Musician();
musician2.setName("Musician 1");
TransactionStatus status = null;
try {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
status = txManager.getTransaction(def);
musicianDao.addMusician(musician1);
musicianDao.addMusician(musician2);
txManager.commit(status);
fail("MusicianException was not thrown when musician's name was not unique");
} catch (DataAccessException ex) {
//now I added this code, even if
//commit thrown error so it has already cleaned the transaction as said in documentation
if(!status.isCompleted()){
//but it apparently didn't clean the transaction as it is still not completed
txManager.rollback(status);
}
}
}
Can you explain this to me? Thanks in advance.