0

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.

Xenon
  • 189
  • 1
  • 1
  • 14

1 Answers1

0

You have not added the full code. However, the reason is that you first commit the transaction and then fail the JUnit test. The transaction will be committed as per your code. If you don't want the data to be committed try the following:

fail("MusicianException was not thrown when musician's name was not unique");
txManager.commit(status);

This will throw an java.lang.AssertionError, therefore the transaction will not be committed.

Name Name
  • 175
  • 1
  • 2
  • 11
  • Thanks, but I have said that commit throws an Exception, so fail is there only to assure commit thrown error. So why then I have to rollback even when in documentation it is said you MUST NOT manually rollback when commit throws exception... Can you explain this to me, please? – Xenon Dec 18 '14 at 22:46
  • This is because you are using Programmatic transactions, rather than container manager transactions. You are expected to rollback. – Name Name Dec 24 '14 at 17:00