Dec 18th, 2008, 11:56 AM
Spring, Hibernate, Junit trying to commit before HQL query
and are trying to retrofit Spring and Hibernate into an existing application. One of the joys of which is cutting over 1000s of Junit tests that are used for both unit and integration testing.
Some of the tests write data to the db which is required for either that test or subsequent tests. We are using hibernateTemplate.saveOrUpdate() to write the data to the db.
Where we have code for the same test retrieving the data using hibernateTemplate.get(type,id), then it works ok, however, there are lots of cases that try to retrieve the data through an HQL query (using hibernateTemplate.find(HQL)) and these fail.
If I programmatically add a hibernateTemplate.flush() after doing the saveOrUpdate() then he HQL works, but it's not really a feasible exercise to do this for all off the tests, so I really need another way of forcing a flush/commit. Any way of doing this?
For info: Our tests currently extend from AbstractTransactionalDataSourceSpringContextTest and we've removed the Transaction Manager from the config and set dependencyCheck to false.
Dec 18th, 2008, 05:39 PM
You may get the hibernate session from the hiberNamteTemplate, and set the flush mode to ALWAYS. That way, hibernate will flush on every query. Anyway, if you put it to AUTO, it should flush when you try to read from the database (Reading with HQL), so perhaps it is set to manual.
Dec 19th, 2008, 11:05 AM
I do set the flush mode to always, however, what I found is that because I'm binding the session to the thread using the TransactionSynchronizationManager, there's a knock on effect in that Spring decides there's no need for a flush to be performed - it goes to HibernateAccessor.flushIfNecessary() but existingTransaction=true so it doesn't flush.
If I don't bind the session to the thread then I get lazy initialisation errors when I try and traverse object trees.
The core application will be using the OpenSessionInView pattern and I was trying to replicate that in the testing, hence the use of the TransactionSynchronizationManager. If there's another way of mimicking the OSIV pattern using Junit, please let me know...
Tags for this Thread