In my previous post I have started describing technology stack we use for typical business system with web interface. As I promised, now I am going into more details and advocating each of our choices. This post is devoted to EclipseLink and why we think it is better than its closest competitor – Hiberante.
For those who want to read why Hibernate is not a choice, I wrote a separate article in my personal blog.
Here I want to focus on what makes EclipseLink better than Hibername.
I would like to define two criteria to compare these ORMs from the business point of view. Then I will go through some technical details to show why EclipseLink is simply better.
The business points are:
Let start with more simple thing – fragility. Just some statistical information. If you open issue trackers of both these products and search for all open CRITICAL and BLOCKER bugs you will see following picture (as for July 26, 2011) :
|Name||Number of bugs||Number of blockers||The oldest blocker|
Well, I think it explains itself. However I can only add we have made this short comparison not because we were curious, but because we really had too many problems with Hibernate stability. And now we have approximately 10 times less.
By predictability I mean an ability for developer to predict how the code he/she just have wrote will behave. Good library should have high level of predictability. However it is not the case with Hibernate. Let me repeat my own post from the blog I already noticed:
Just a sample:
User user = loadUser(id);
It is a good old explicit statement which obviously loads user. How many SQL statements this call should execute? Normal answer is “one statement”. Something like
select * from users where id=?
But the true is in Hibernate it can be any number. Thousands or millions. And the most cool feature is this number may be easily (and often unintentionally) changed in several different places of the code!
It is because of autoloading. When you designed User refers to a collection of Roles you most probably never thought that one of your colleagues will later add ref from Role to let say Permission. And another one (couple of weeks later) from Permission to something else.
As a result, your fast and pretty loadUser now executes 100 times slowly. And even when you accidentally find it you will have to analyze the whole model to understand what happened and then start with huge refactoring to make your code fast again without breaking codes of you colleagues (that relies on Permission collection now!)
Now let me explain why it does not happen to you with EclipseLink. Two facts:
1) This happen only to “eager” links. And does not happen to “lazy” links.
2) With EclipseLink you have no any reason to use eager links at all, while with Hibernate you have the reason for it
Lazy links and Lazy Initialization Exception
The reason is lazy links only works inside transactions in hibernate. It means if you load an object from database and close database connection such links will no longer work. If you try them, they will result in lazy initialization exception. So, standard strategy in hibernate is either to make a lot of links eager or to add a big set of methods like:
With EclipseLink it is not the case. Lazy links will work even if you accidentally closed database connection. In such a case, EclipseLink will simply take a read-only connection from connection pool, execute loading and then put the connection back to pool. It will do it hiddenly, without bothering developer.
So, if developers simply make all the links lazy, it will work with EclipseLink and will solve the problem described above.