I'm developing a Java/Seam/Hibernate/Glassfish application with two threads:
ScheduledExecutorService
) and acts on the current "state" of each message.Have come across an integration test problem: It doesn't seem to matter how long Thread #2 waits for a new row to be added by Thread #1, it just isn't added during the test so the expected call isn't made. Then sure enough, after the test has failed a new row pops up - but too late. Not sure if this might be a design problem - Thread #2 currently gets a Seam context using Lifecycle.beginCall()...Lifecycle.endCall()
. So my understanding (which may be wrong) is possibly the problems are due to there being two separate Hibernate sessions for the two threads - so the one reading doesn't know about the latest information from the one writing?
There may be different ways of fixing this but my current thinking is couldn't I just force Hibernate to actually add a record to the table immediately when I call save()
/ flush()
or even manually commit a transaction? No luck with any of these - makes me wonder if there is some kind of managed transaction being used behind the scenes. Grateful for any advice...
For info, here's the gist of the code that adds a record:
// Obtain Hibernate session
Session session = (Session) Component.getInstance("hibernateSession");
// Create request
Request newRequest = new Request();
// newRequest.set<blah>();
// Save the new request to the database
session.save(newRequest);
// Have tried session.flush(), transaction.commit() etc. here.
// Nothing seems to put the record into the database straight away.
Not sure if this is relevant but here is the Hibernate configuration:
<property name="transaction.flush_before_completion">true</property>
<property name="connection.release_mode">after_statement</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>
<property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="current_session_context_class">jta</property>
(As this is an existing application owned by the customer I don't have the right to change the Hibernate config.)
Your guess is good.
You are using a JTATransactionFactory
, so the transaction is demarcated by JTA (i.e by the container).
The method you are using to save the Request
(here I presume it is defined in an EJB ) needs to be annotated with a transactional annotation: @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
, so when the method ends, the transaction gets committed.