A kind of disclaimer: I know, Hibernate was really good in the old good time when it was created. Maybe it was even revolutionary. The goal of this article is NOT to tell something bad about its authors.
However I am sure it is time for it to die. Want to know why?
I have at least 4 reasons to not use Hibernate:
- It is invasive
- It is nor predictable
- It is designed to fight against application performance
- It is fragile against database schema and code refactoring
After this introduction I will focus on each point and explain what I mean.
Hibernate is invasive
Or , in other words, it is not ready for integration with 3d party systems. Everyone who ever tried to serialize hibernate model will agree. It is just impossible, because Hibernate adds its own (non serializable) code , like lazy collections, inside you model. And this fact is enough to prevent your model from being transferred through any kind of protocols. One of the best sample is when you try to integrate hibernate with Google Web Toolkit , a nice AJAX framework from Google. To do it you have to add special DTO layer, or to use some complex “POJO cloner” like this. In other words , in order to fight the obvious mistake in hibernate design you have to increase
complexity fragility of your product.
Hibernate is not predictable
Hm. I have told it is not predictable? Well, I mean it does not help you to build predictable development process in the team environment. As it is too sensitive to local changes. 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 week 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!)
One may object the situation above is the result of inaccurate model design and the poor development process. But I am sure this feature is potentially dangerous. Something similar to “goto” operator. Maybe even worse, because it causes performance problems hidden till the load tests or (in worst case) till you are in production.
Hibernate is not performance friendly
Hibernate performs well when you are using it for manipulating objects (aka for CRUD operations). But it goes completely bad when we try to use it for querying database.
Note: Generally, I never understand why almost each ORM manufacturer includes both features in their product: CRUD and querying. In fact, these 2 features has almost nothing similar and can be provided separately, like e.g. this nice product does.
Ok. I was talking about the querying in Hibernate. If you’ve ever written not a trivial query in HQL or via Hibernate criteria and then have looked at resulting SQL, I guess you’ve already got my idea 🙂
If not, just try it. You will see something like 1.5 pages length absolutely not readable monster. Well, sometimes we really need to write long queries to achieve some special results. But this is not the case. Each normal developer could write much shorter, more pretty and more efficient SQL query manually. In fact, in all our real life hibernate-based products we finally ended with it for about a half of all the queries. And it is not because we like manual SQL. It is because hibernate does not provide any usable way to make its “native” queries to perform good.
So, when I anyway have to use plain SQL for half of the queries why to mess with HQL at all? From my point of view Hibernate would not lose anything if all the querying would be simply thrown away. (It is except for nice tutorials where they deal with trivial models)
Hibernates does not allow refactoring
Like all the products from the previous generation, Hibernate is not refactoring friendly. I guess in that time nobody could imagine such amount of refactoring as we have in real life projects now.
By refactoring I mean both – refactoring of database schema and refactoring of code.
Problem with code is simple: HQL queries (as well as SQL queries or hibernate criteria) are string based. So, if you change the database schema, nothing will tell you which of your queries does no longer work. So, the only way to deal with really big project is to write a lot of unit tests and be in hope at least one of them will crash and will show you the problem. More elegant solution is to use some tool which is not string based (like jequel). And I wonder why neither of major ORM authors did not implement something similar yet.
Refactoring of schema is another headache. What hibernate does when you change the model can be called only
alternative artificial intellect: you never know if it will crash on real database or if it will magically update your schema. In fact, I do not know any real life product where they use hibernate schema auto-update feature at all. Instead, people use something else to keep their schema updated. Some prefer old school SQL scripts, other – modern tools like liquibase. Both approaches work well. Much better than hibernate does.
So, when you decide to use Hiberante in your project you will have:
- To use tricky and fragile techniques to serialize your model
- To not allow your team modify the model and have one separate “model architect” instead
- To write most SQL queries manually or with 3d party tool
- To update your database schema manually or with 3d party tool
And you will get all these inconveniences for the only 1 Hibernate feature, which is not bad: CRUD operations with your objects!
I do not know how about you, guys , but for me it is too high price…