I use Spring and Hibernate in a web-app,
SessionFactory is injected into a DAO bean, and then this DAO is used in a Servlet through webservicecontext.
DAO methods are transactional, inside one of the methods I use ... getCurrentSession().save(myObject);
One servlet calls this method with an object passed.
The update seems to not be flushed at once, it takes about 5 seconds to see the changes in the database. The servlet's method in which that DAO's update method is called, takes a fraction of second to complete.
After the @Transactional method of DAO is completed, flushing may NOT happen ? It does not seem to be a rule [ I already see it ].
Then the question is this: what to do to force the session to flush after every DAO method? It may not be a good thing to do, but talking about a Service layer, some methods must end with immediate flush, and Hibernate Session behavior is not predictable.
So what to do to guarantee that my @Transactional method persists all the changes after the last line of that method code?
getCurrentSession().flush() is the only solution?
p.s. I read somewhere that @Transactional IS ASSOCIATED with a DB Transaction. Method returns, transaction must be committed. I do not see this happens.
Hibernate deals with database specific transactions, whereas spring provides a general transaction management service. @Transactional is a nice way of configuring transaction management behaviour.
The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.
flush() will synchronize your database with the current state of object/objects held in the memory but it does not commit the transaction. So, if you get any exception after flush() is called, then the transaction will be rolled back.
@Transactional helps you to extend scope of Session . Session is open first time when getCurrentSession() is executed and it is closed when transaction ends and it is flushed before transaction commits. In Spring, If we use getCurrentSession() in non-transactional context we get an exception.
Once the "top level" @Transactional method has completed (ie the method called from your servlet), then the transaction should be committed, and the default Hibernate behaviour is to flush on the commit.
It sounds like something odd is happening and you should do a bit of investigating.
Investigate your logs, in particular I would set the logging level to DEBUG on your Transaction Manager to see exactly what the transaction manager is doing.
Also, set the logging on for hibernate (set show_sql to true): this will output to System.out when flushing is happening and this might give you some clues.
Do report back if you find anything interesting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With