iBatis better than Hibernate for GUI applications?

time to read 5 min | 853 words

Hm, how about this for nose butting? I am going to talk about Java, the language I write an applet with, and iBatis, the ORM I never used. At any rate, this post was forwarded to me, and I found it interesting enough that I think that it deserve a comment.

First, let me run through some things that I do not believe to be correct, and then I will touch the subject in a more general fashion.

With Hibernate, each time you run a new HQL query, Hibernate will reload all objects in the session cache into memory.

That is not the case. Or at least, that sentence is not worded correctly. All the objects that are loaded from the query will be put in the session cache, but there is not reloading done. The session cache is always in memory. This sentence and several others down the road seems to indicate a problem with Hibernate's usage, getting SELECT N+1 or maybe Overly Eager Fetch.

In an RCP application, however, this behavior can kill you. If the entire object graph that a single client knows about is a half a gigabyte, then as the user interacts with the application, eventually that entire object graph will wind up in the session cache. The result is that every time your application runs an HQL query, before Hibernate can even translate the query into SQL and optimize it, it must reload 512 megabytes of objects into its session cache.

That is not even remotedly close to the way Hibernate works, I must maintain. I do not understand the meaning of reload objects into its session cache, though, reload from where? From the database? Without further information, I can only assume that the mapping for Hibernate were setup incorrectly, and that caused a lot of unneccesary reads.

What does happen before a query is run is that the items are checked for changes, and if there are changes, and if Hibernate detects that they can affect the result of the query, it will persist those changes (assuming you are in AutoFlush mode).

Moving from a mixture of HQL and SQL to all queries being in SQL has dramatically simplified query writing, debugging, and optimization.

There is a time and place for using SQL in Hibernate, but those are usually very rare edge cases. If you are constantly using SQL in Hibernate, you are doing something wrong. David also mentions that they were building queries using string concatation, which is consider as a big DO NOT DO, that is what the criteria API is for.

Now, for the real issue:

Working with Hibernate or NHibernate in a desktop envrionment can be a little more challanging than on the web. The issue is that you need to make sure that your session doesn't live for the duration of the application. The reason is, of course, the session cache. Using a single session for the application would basically be a memory leak, since the objects would never be released.

Common ways to solve this problem is to use Session per Conversation (think about a wizard or a dialog), to reduce the amount of time that you are keeping items in memory. This is usually something that you need to pay attention to when you load large object graphs, and then you can use the Evict() method to remove it from the session cache.

Personally, I find that it is easier to simply manage the session and not the entities. I would also usually combine this with a file based second level cache, NHibernate has the Prevelance cache that can be used, and I am sure that Hibernate has similar cache implementations.

The book Java Persistence with Hibernate have some information about it, including a sample application that I really ought to port to .Net one day.

I had the pleasure of building several desktop applications that used NHibernate, and I really liked the options that it gave me there (no need to worry about loading too much objects, second level cache that is persistant, etc). In short, you can safely use Hibernate or NHibernate in a desktop application, there are several things that you should be aware of, like the session lifetime, and that you need to close the session at the end of a conversation, but those are simply things to implement, and the benefits are really great.