This blog is subject the DISCLAIMER below.

Monday, June 08, 2009

Handling Hibernate Session

Handling hibernate session is so important, and the way of handling the session reflects with the performance of the application.

You can handle the hibernate session per service. It means with each request for each service you will open new session, at the end of the service, you will close the session. In this approach you have to be sure that you don`t need the session again (lazy fetching for example ).

p.s) if lazy fetching is false it will affect the performance.

Another approach of handling session is session per view. When an HTTP request has to be handled, a new Session and database transaction will begin. Right before the response is send to the client, and after all the work has been done, the transaction will be committed, and the Session will be closed. In this approach you can user the Filter in servlets APIs . this approach is called session-per-conversation and used while implementing long conversations.

The third technique and the most recommended technique is using java transaction APIs. Hibernate can automatically bind the "current" Session to the current JTA transaction. This enables an easy implementation of the session-per-request strategy with the getCurrentSession() method on your SessionFactory:

try {
    UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");
                            
    tx.begin();
 
    // Do some work
    factory.getCurrentSession().load(...);
    factory.getCurrentSession().persist(...);
 
    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}

Finally If you don't have JTA and don't want to deploy it along with your application, you will usually have to fall back to JDBC transaction. Instead of calling the JDBC API you better use Hibernate's Transaction and the built-in session-per-request functionality:

    factory.getCurrentSession().beginTransaction();

3 comments:

Youssef Mamdouh said...

Good article, however, there is another alternative way only in case you use spring. Spring provides some extra support for using hibernate by marking the methods that needs transactional support in a certain class, for example; if you have a service class that calls DAOs, then, the logic in these methods are transactional, either done completely or rolled back, spring uses a simple proxy class to wrap the service class methods and automatically commit or roll back the database actions done according to the success or failure of a method. for more details see TransactionalProxyFactroyBean class of spring.

Unknown said...

Yes, this same approach can be used in JSF by providing our custom ActionListener implementation

[code]
public void processAction(ActionEvent actionEvent) {

try {

if (!TransactionUtil.isActive()) {
TransactionUtil.begin();
}
superActionListener.processAction(actionEvent);
if (TransactionUtil.isActive()) {
TransactionUtil.finish();
}

} catch (RuntimeException ex) {
TransactionUtil.rollback();
PageUtil.processPageException(ex);
}
}
[/code]

I's sure that there is a way to do this in .Net world.

mhewedy said...

@Youssef Mamdouh,

I've implemented a simple TransactionProxy:

http://m-hewedy.blogspot.com/2012/06/using-dynamic-proxies-to-centralize.html