One of the most populare articles in this blog so far ist the one about, well: Hibernate Sessions in Two Tier Rich Client Applications. Although the original article is writen in german I keep refering to this article, even in english communities. Therefore I decided to break my habit of writing articles in german only and provide a english version which you are reading right now.

This is NOT a direct translation so there might be some differnces in scope, focus and detail.

Everybody working with Java and Databases is probably aware of Hibernate. It is a great solution for mapping a database schema to a object model. It is used in hundreds of applications. So on my current project we decided to use it as well. But big surprise. While Support in the user forum of hibernate is pretty good most of the time we hit one kind of a problem which had no apropriate solution available: How to handle Sessions in a Two Tier Hibernate Application (Swing or SWT typically).

How could such a essential problem be unsolved? Well Rich Client Applications are not hip anymore. Everybody goes for web applications and in that context the session handling is well understood and there is a easy straight forward solution that works in most cases: On each request open a session, do all your work including constructing the result (e.g. JSP) , close the session. But there is no equivalent for a request in a swing application. And since Rich Client Applications are kind of old fashioned nobody bothers to find (and write about) a clean solution for this problem.

We tried a lot of things, starting with the antipattern of a single session per application. This doesn't work at all for any kind of serious app for the following reasons:

Of course if you write a really small simple application this might work, but not for us. As said before we tried a lot of things to solve our problem in the assumption that our requirements are so common that it can't be hard to find the solution. We were wron. So if the solution to a problem isn't easy to find, what should be your first step? Wrong (probably)! Your first step should be to exactly identify the problem. In this case this meant: What are the requirements we had? What are the relevant features/limitations of Hibernate? The requirements were:

The relevant properties of the Hibernate session are

If you look at it in this compact form it is rather obvious that you can't have your cake and eat it too. The automatic refresh in all views of an object would be easily implemented, when there is only one session. But we simply couldn't do this. So the decision was made that the automatic refresh is (obviously) not as important as clean transactional control plus lazy loading. So we will have more then one session. But which part of the application is using which session? The Hibernate site uses the term 'Unit-of-Work'. Each unit of work should be contained in its own session. But this is basically back to step one. A request in a webapp ist a unit of work, but where is a unit of work in a rich client app? Imagine this example: The user fires up the application and opens a search dialog resulting in a list of objects. Clearly we are accessing the database, so we just startet a unit of work. Now she double clicks an item in the list. The entity gets opened in a editor, she edits it and hits save. Work commited, transaction closed, unit of work ended. Wow, thats easy, isn't it? No it isn't: She clicks on a different item, edits it, saves it. So now we have opened one session and closed two sessions. Not good.

The answer is actually fairly easy once found: Use one session per frame/internal frame/dialog. Modal dialogs use the session of the frame the got starteted from. Background tasks get their own session. The critical point is the transfer of objects from one frame to another. It is tempting to just pass the object but then you have a object from the wrong session in the frame. Instead pass just the Id (the primary key) and use that to load the object in the new session. This approach solved most of our problems nicely.

Most problems? Yes and no. We have some things that we don't like to much. I think I know how to solve them but I haven't implemented them yet. So I can't really promis anything.

If you are going to implement this kind of session handling I strongly suggest to use a director/mediator pattern for all your frames. While always a good idea, it becomes important in this case because it gives you a well defined spot to do your session handling. And of course you should be aware of the alternatives:

In any case I how this write up shed some light on the issues and helped to make a informed decission.