0

I got some unit test that stores some Person data into the database. To do this i use the EntityManagerFactory.

@Test
public void findPersonById() {
    personDao.savePerson(new Person("Hans"));
    Person person = new Person("Peter");
    personDao.savePerson(person);
    Long id = person.getId();
    flushAndClear();

    person = personDao.findById(id);
    assertThat(person.getName(), is("Peter"));
}

where

private EntityManager entityManager;

public Person savePerson(Person person) {
    entityManager.persist(person);
    return person;
}

and

public Person findById(Long id) {
    Person person = entityManager.find(Person.class, id);
    return person;
}

with this Base-Test-class

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

import org.junit.After;
import org.junit.Before;

public class AbstractDaoTest {

    protected EntityManager entityManager = Persistence.createEntityManagerFactory("DefaultPersistenceUnit")
        .createEntityManager();

    protected PersonDao personDao = new PersonDao();

    @Before
    public void setUp() {
        personDao.setEntityManager(entityManager);
        entityManager.getTransaction().begin();
    }

    @After
    public void tearDown() {
        entityManager.getTransaction().rollback();
    }

    protected void flushAndClear() {
        entityManager.flush();
        entityManager.clear();
    }
}

My unit test runs green but when i debug this test, i can't see any data on the db (using squirrel). It doesn't matter in which step the debugger currently is, the Tables are always empty. I am using the following configuration for squirrel:

jdbc:h2:file:~/test;DB_CLOSE_DELAY=-1;LOCK_MODE=0;AUTO_SERVER=TRUE
with Driver: H2

Can you help with this issue?

Chris311
  • 3,794
  • 9
  • 46
  • 80

1 Answers1

1

This has happened because your test cases are not properly designed.

Firstly, If you wish the data to be added to the database, you should commit the changes after any update/insert operation. You have to do a rollback only if there are any exceptions during transactions.

Design your tests some thing like this.

        @BeforeTest
        public void setUp() {
            personDao.setEntityManager(entityManager);
            entityManager.getTransaction().begin();

        }

        @AfterTest
        public void tearDown() {
            // TODO clear all inserted data either using sql statement or JPA
            //Rollback only if there is any exception
            entityManager.getTransaction().rollback();
        }


        @Test
        public void findPersonById() {
        Long id = System.currentTimeMillis();

            personDao.savePerson(new Person(id,"Hans"));
            entityManager.flush();

           // TODO your assert statements go in here
           /* Data is visible till here during your debug. 
              Once AfterTest is executed then the your data would be rolled back
            */
        }

I have used testNG as my Unit testing tool, pls use appropriate tool based on your requirements. Also, if you are enityManager.flush() insert/update statements would be sent to the DB but wont be committed until commit instruction is sent to the DB by HIbernate. Pls refer this answer for further details

Community
  • 1
  • 1
Patton
  • 2,002
  • 3
  • 25
  • 36
  • The tutorial i work with says: "If you use squirrel, the database is configured in a way so that changes are visible before commits." Sadly i can't give you the link to this tutorial as it is in an intern network. Do such settings exist? – Chris311 Apr 21 '14 at 12:25
  • The rollback is only for testing-purposes. I think the author did this, to prepare the db to be just the same before every execution. – Chris311 Apr 21 '14 at 12:32
  • If that is the case, please use sql statements to clear what you have inserted. IF you do a rollback, what ever you have inserted would be deleted. BTW, your tests are passing because you have flushed your inserts. – Patton Apr 21 '14 at 12:37
  • One thing is quite clear; if you rollback, your changes won't be visible in the database! If you want your inserts to be visible you have to commit! – Patton Apr 21 '14 at 12:39
  • I want them to be visible only during debug! – Chris311 Apr 21 '14 at 14:38
  • As far as I know you can do that only after Flush and before rollback happens. I will update my answer based on your comments over here – Patton Apr 22 '14 at 05:19
  • No, that is not true. I debugged and stopped right after (as well as before) `entityManager.flush()`, but still nothing to see on the db. – Chris311 Apr 22 '14 at 15:48
  • If i work with commit, i can see the changes; but if i debug the code i posted, i can't see any changes. Something must be different. What can we do to find out what? – Chris311 Apr 23 '14 at 07:09
  • you said you are using h2 right? why don't you open the same on h2 console and check? I did check on h2 Console with the same url and was able to see the changes before rollback. One more possible thing could be check your DB connection setting on the tool you are using, check out if there is something like `TRANSACTION_READ_COMMITTED` if that is the case you wont be able to see the changes – Patton Apr 23 '14 at 07:23
  • I have no idea how to use h2 console. I tried it with [this](http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/h2-console/) example, but i failed in configuring maven as "http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd" does not exist. Neither could i found something in the settings. I am becoming desperate. – Chris311 Apr 26 '14 at 14:42
  • what is your App server? Is it Jboss 7.x? If so go to `${JBOSS_HOME}/modules\system\layers\base\com\h2database\h2\main` run the h2 jar it would start h2 open the same in the browser. By default, the url for the console would be `http://localhost:8082`. – Patton Apr 28 '14 at 03:14