Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Session flush behaviour [ and Spring @Transactional ]

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.

like image 367
EugeneP Avatar asked May 20 '10 18:05

EugeneP


People also ask

What is the difference between spring transaction and Hibernate transaction?

Hibernate deals with database specific transactions, whereas spring provides a general transaction management service. @Transactional is a nice way of configuring transaction management behaviour.

What does @transactional do in Hibernate?

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.

Does session flush commit transaction?

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.

Does @transactional close session?

@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.


1 Answers

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.

like image 111
Dick Chesterwood Avatar answered Oct 06 '22 10:10

Dick Chesterwood