0

I've been asked to write some coded tests for a hibernate-based data access object.

I figure that I'd start with a trivial test: when I save a model, it should be in the collection returned by dao.getTheList(). The problem is, no matter what, when I call dao.getTheList(), it is always an empty collection.

The application code is already working in production, so let's assume that the problem is just with my test code.

@Test
@Transactional("myTransactionManager")
public void trivialTest() throws Exception {

    ...
    // create the model to insert
    ...

    session.save(model);
    session.flush();

    final Collection<Model> actual = dao.getTheList();

    assertEquals(1, actual.size());
}

The test output is expected:<1> but was:<0>

So far, I've tried explicitly committing after the insert, and disabling the cache, but that hasn't worked.

I'm not looking to become a master of Hibernate, and I haven't been given enough time to read the entire documentation. Without really knowing where to start, this seemed like this might be a good question for the community.

What can I do to make sure that my Hibernate insert is flushed/committed/de-cached/or whatever it is, before the verification step of the test executes?

[edit] Some additional info on what I've tried. I tried manually committing the transaction between the insert and the call to dao.getTheList(), but I just get the error Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started

@Test
@Transactional("myTransactionManager")
public void trivialTest() throws Exception {

    ...
    // create the model to insert
    ...

    final Transaction firstTransaction = session.beginTransaction();
    session.save(model);
    session.flush();
    firstTransaction.commit();

    final Transaction secondTransaction = session.beginTransaction();
    final Collection<SystemConfiguration> actual = dao.getTheList();
    secondTransaction.commit();

    assertEquals(1, actual.size());
}

I've also tried breaking taking the @Transactional annotation off the test thread and annotating each of 2 helper methods, one for each Hibernate job. For that, though I get the error: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here.

[/edit]

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
ds390s
  • 587
  • 1
  • 6
  • 19

1 Answers1

0

I think the underlying DBMS might hide the change to other transactions as long as the changing transaction is not completed yet. Is getTheList running in an extra transaction? Are you using oracle or postgres?

aschoerk
  • 3,333
  • 2
  • 15
  • 29
  • This is H2 in-memory database. I tend to agree, that it has something to do with transactions. The transaction is driven by the annotation on the test method, though. I've tried manually committing the transaction, but it just errors. I'll expand my question to include the testing that I've done with this. – ds390s Jul 25 '17 at 15:57
  • This mix of declarative and explicite transaction management would not be allowed in ejb. So I can not tell what to do. But perhaps: https://stackoverflow.com/questions/24338150/how-to-manually-force-a-commit-in-a-transactional-method can help? Or you could encapsulate the insertion into a method done with "REQUIRES_NEW". Or, at last the query in the dao does not work correctly. – aschoerk Jul 26 '17 at 03:08