My initial reason for learning Hibernate was to make sure I knew enough in an interview situation if it came up. I also needed to recommend a persistence technology for a couple of projects that I am involved in and having heard so much about Hibernate I assumed that it would be a good fit.
The biggest advantage that I can see with Hibernate is that it allows for rapid prototyping and development of new applications. That alone might be sufficient reason to use it on some projects. However, once you get past the simple initial requirements of persisting objects and get to the point where you need to run complex queries across a number of tables and perhaps use aggregate functions and other SQL capabilities, things get much more complex because Hibernate uses its own HQL query language that the runtime translates into SQL and this forces the development team through yet another learning curve. Another issue with this approach is that you can’t simply develop and test SQL and then paste the working SQL into your source code or configuration files but have to then re-code them in HQL.
Spring JDBC isn’t directly comparable to Hibernate because it doesn’t have the same goals (it doesn’t provide caching or object relational mapping for instance). However, it is certainly an alternative choice for implementing persistence. Spring JDBC provides a very small abstraction layer over raw JDBC and does this in an elegant way. Setting up a new project does require more thought and effort than using Hibernate but that time is paid back once more complex application functionality is developed.
However, the real surprise for me was how the performance and scalability compared between the two approaches. I spent a couple of days building a realistic subset of the application I was recommending the technology for and then ran benchmarks against a large database on dedicated test hardware. The results showed that Hibernate didn’t scale at all well compared to Spring JDBC for this application.
I posted some questions to the Hibernate forum to validate the approach I had taken and I received the rather terse and unhelpful reply “This is called 'A useless microbenchmark' and has been addressed a thousand times.” from a member of the Hibernate team. I did some reading of the Hibernate Performance FAQ and found some interesting statements in there, such as "We claim that Hibernate performs well" and "Many people try to benchmark Hibernate. All public benchmarks we have seen so far had (and most still have) serious flaws.". It almost seems like it is taboo to question Hibernate performance. I don't understand this defensive stance since most developers would recognize that there is a trade off between ease of use and performance.
The bottom line for me is that for my application, Spring JDBC scales much, much better, which will save significant hardware dollars (or pounds). Spring JDBC also doesn't require much investment in terms of learning curves and I can have full control over the SQL I use which in turn will help me squeeze maximum throughput out of the hardware that is available to me.
If you're considering using Hibernate on your projects I highly recommend running some performance tests based on your application requirements before getting in too deep.
[14th Oct 2007] Wow! This article has certainly attracted more attention than I expected. I would like to draw attention to that fact that I state in the above article that Hibernate does not scale well for *this* *particular* *application*. Many people seem to think I'm saying that Hibernate doesn't scale well, period. That's not what I'm saying so please read again before posting comments :-)
Labels: hibernate, performance, persistence, spring


21 Comments:
You might also consider iBatis. It is a good balance between JDBC and Hibernate in that it populates your POJOs but you have full control over the SQL.
However, I'm a bit torn on whether maintaining iBatis XML files is better than coding Row Mappers.
The previous comment mentioned the use of a mapper solution with Spring JDBC... Dozer is a powerful Java Bean mapper that automates most of your work... Might be worth looking into it...
http://dozer.sourceforge.net/
Frankly: the fact that hibernate scales greatly is proven by thousands of projects (including ours, the biggest italian online grocery store, where hibernate runs without a flaw in a context where we didn't ever felt the need to activate second level caching). You run a couple of tests on your own and then decide that hibernate does not scale as well as spring jdbc, ok, and then you expect someone else to explain this to you? I'm sorry, but at this point in the history of the technology world hibernate does not need anymore to prove its scalability: on the contrary, YOU need to prove you are smart enough to use it without doing one of the (not too many) stupid things that one can do while using it.
By the way: in 2003 I was challenged to show that hibernate could run in a way that was "not too outperformed" by a raw jdbc solution, by providing a hibernate-based solution of a scenario someone was building a jdbc solution for. The hibernate-based one resulted about as fast as the other, just a little bit faster.
Immanuel - I'm glad to hear that Hibernate is working well for your application. Unfortunately it does not scale well for *my* application, which is the only thing that really matters to me right now.
Can you provide me with a single link to an article that *proves* that Hibernate scales greatly, as you claim? I doubt it. Can you prove that it scales well for *my* application? Obviously not.
According to Gavin King, "Hibernate really starts to shine in applications with very complex data models, with hundreds of tables and complex interrelationships". My application only has around 50 tables so perhaps that's why Hibernate isn't shining for me.
I can see that Hibernate can outperform some JDBC solutions through caching, but my application is caching data at the application level so that Hibernate feature does not provide any value to *my* application (which is the subject of the post after all).
Can you send me the empirical data you have that proves that Hibernate scales greatly? I would genuinely like to see this and I'd be happy to post it on my blog so everyone can benefit from this.
Oh well, isn't ORM just a lie.
JPA/Hibernate/ORMs can be interesting if you have developers who are not used to SQL and relational databases (if they don't know that, I'd seriously question their qualification as developers though, but well, I guess it happens).
With experienced developers who have a deep understanding of SQL and relational models, I find ORMs to just be in the way: for anything but trivial tables without relations, you end up trying to find how the heck the ORM will do that SQL query you have in mind.
Object-Relational Mapping is a lie, it just doesn't fit. At all. Only few databases are capable of the most basic OO features (except maybe for Oracle and PostgreSQL that have basic support for table inheritance and handle the gory discriminator column details behind the curtain), and the OO model doesn't fit to the relational model too well either.
Personally, I prefer to see the plain old SQL, test it outside of my Java code, analyze it, optimize it, and Spring JDBC is an elegant way to save a lot of typing (the declarative transaction boundaries using Spring's proxies are a much more important feature though). While I'd love to see a better approach, DAO and DTO aren't dead.
loki - I agree with your point about developers not knowing SQL and relational databases. I'm a big fan of the Java language but it is just one of the skills that I need to build business applications. Good knowledge of relational database technology and SQL is essential in my view when building typical business applications. The funny thing is that I've worked for a very well known company here in the UK that only allows database access via stored procedures and doesn't trust developers enough to let them access tables directly (this is a mission critical database that simple cannot go down). This is the other end of the spectrum from Java developers using Hibernate without understanding SQL but equally bad. A successful project should have good co-operation between Java specialists and database specialists (sometimes these can be the same people) so that each technology is used appropriately. Some things are better done in Java, some things are better done in the database. Anyone that claims that a single technology or product is the best solution for all possible scenarios probably hasn't seen enough scenarios!
Hibernate works great for certain things, not so great for others. Surprisingly, it can be fantastic for bulk operations. I use it at a one of the worlds largest publishing companies for processing logs. It can handle bulk loads of several million rows in minutes -- to a database in another part of the country. (Granted, the performance will stink until you configure it correctly, which may take you a day or two.)
One place I've seen Hibernate perform weakly is when you are trying to do particularly nasty queries (deep joins, etc), in which case I use Spring's JDBCTemplate to look up IDs and Hibernate to populate. But if you're not going to use Hibernate's caching, then you might not want to bother. That's most of the value for me.
I think the best argument I've seen for ORM tools in general is that they produce CONSISTENT results, not the BEST result under all conditions. I think everyone that has dealt with Oracle say, has experience the "Threshold" event, where your tight finely hand tuned queries are working great one day, then a couple more rows are added to a couple of tables, and your subsecond result starts taking many, many minutes to return,
the explain plan is totally different, indexes ignored, etc. By only using short, stupid SQLs, while the result might not be as elegant, it is also much less likely to suddenly go south.
It's unlikely that a general-purpose solution can ever be as highly optimized for a particular purpose than a specific solution.
That is to say, if you do a really good job of your JDBC implementation, it might be both sufficient and higher-performing than Hibernate for that same job.
OTOH, I think there are enough instances of Hibernate in production to show that it can scale well. The odds that we can prove it scales well for your application are low, since we don't know your application.
That said, unless your application is exceptionally strange, I would argue that Hibernate can probably be performant (although perhaps less so than a very well-built tailored solution).
Like any library, it requires some experience; it's quite easy to configure/develop a hibernate solution that's not very performant; seems likely that if this is your first Hibernate solution, that's probably the case.
That said, no-one's forcing you. If you like Spring JDBC, more power to you; it's not a bad choice.
Geoffrey - absolutely. I really never would have expected Hibernate, or any other framework, to be as efficient as hand coded JDBC/SQL and I would have been happy enough with a small overhead. The thing that frustrates me the most is that when I posted my source code, config, etc to the Hibernate Forum seeking guidance on improving the performance I get a pretty rude response from one of the people behind the framework. Maybe I'm too used to working for commercial software houses but being rude to potential adopters of your product isn't really all that helpful. Maybe I did do something wrong. My original post to the Hibernate forum is here:
http://forum.hibernate.org/viewtopic.php?p=2362186#2362186
@loki
If you think in SQL and code in HQL, you will be disappointed. Hibernate is a different thing, and to appreciate it you must study it and use its tools. There's no other way. Translating queries from SQL to HQL is really a bad idea, even if that translation happens in mind.
Having used SQL for ten years, I finally decided to learn Hibernate, and I'm very happy with it since I like OO programming and I work better if I can express my queries that way.
Our projects made with Hibernate run as fast as our other projects. This is just a qualitative measurement, but it's enough to feel confident that we can keep using Hibernate in future.
I'm not posting here to say that Hibernate is better than SQL or other ORM frameworks. I just want to point out that it has proved to work well, and this can't be cancelled saying that "ORM is a lie".
Finally, I can't accept that one that uses ORM frameworks is supposed not to know SQL enough. ORM is not a remedy for bad SQL skills. I see ORM (and especially Hibernate) as a way to express mappings and queries in a way I like more, and since it performs well and is maintainable, I have made it my DB approach of choice.
Sorry, but statements like "hibernate is less scalable as XXX" are bit on nonsense, because there are so much factors affecting scalability, also so much different types of scalability one could think about.
Could you please clarify your Use Cases and which kind of scalability you are looking for?
I'm not surprised you got a short response from the Hibernate team. Even I'm tired of this argument and unlike the Hibernate team I don't hear it ever day. Either that or Gavin's still pissed about growing up in Geelong!
Yes Hibernate is a complex tool, that requires more than a couple of days before you will be productive with it.
What exactly do you mean by hibernate doesn't scale? Using a ORM in conjunction with a distributed 2nd level cache is a very effective approach to scaling an application.
Even Google builds applications with Hibernate, which makes me think there must be something to it.
@renat, @baker .. I actually said that hibernate doesn't scale well for *this* application. I wasn't making a sweeping statement that "Hibernate doesn't scale" as many people have inferred from my article Really, go read it again. I'm sure that even those who are completely sold on the Hibernate approach wouldn't disagree with the recommendation at the end of the post encouraging developers to run performance benchmarks before committing to hibernate. The same applies to any technology. As I understand it there are some situations where Hibernate excels and caching seems to be one of the great benefits compared to raw JDBC. However, that doesn't benefit my application since caching is already implemented at the application level.
There is a comparison of Hibernate vs iBATIS vs raw JDBC here:
http://www.devx.com/Java/Article/33768?trk=DXRSS_JAVA
Hibernate performance is quite adequate for most situations. IMHO, having moved a Spring JDBC based app [ https://jtrac.dev.java.net/ ] to Hibernate [ http://jtrac.info ] I would not go back, the productivity is far better with Hibernate.
What I recommend to the teams I work with is not to do premature optimization, but later Hibernate offers a ton of ways to boost performance for those tricky parts of your app, like caching and even resorting to native SQL if you need.
That said, I've seen that it is very easy to mis-use Hibernate so that the SQL that gets generated would be a DBA's worst nightmare. But this is not really a problem with Hibernate, with great power comes great responsibility.
If you really prefer SQL and JDBC, Spring JDBC templates and maybe iBatis are the "mainstream" solutions out there. Personally, I prefer something as simple as Persist (http://code.google.com/p/persist/) which is quite fast for my current needs.
Andy, quite a stir you have caused with that post hugh! :-)
I am a bit surprised that both you and the commenters haven't mentioned how hibernate and jdbc-template best supports domain modelling in the application.
In my opinion, this is far more important, than comparing performance on raw jdbc against hibernate or other ORMs. As long as they are in the same orders of magnitude of performance numbers, it really doesn't matter that much.
I would argue, that hibernate (and other ORM tools) better support domain driven design and domain modelling, than jdbc-template and raw jdbc does. Things like automatic management of relations and loading of complete domain objects matter here (in my opinion). You can certainly do the same thing with jdbc-templates, but you will have to write more code.
Perhaps not surprisingly, this is also what makes ORM tools more "hard" to use properly. You will have to know a bit about what a particular ORM tool does "behind the scenes" to support all this automagic. Especially to avoid doing some "really bad performing code". Stuff, that you would see right away, if doing raw jdbc, because it is more right in your face.
So, for me, I prefer getting to know my ORM tool deeply (which takes time), and then reap the benefits of all the extra stuff it can do for me on a higher layer than raw jdbc.
Andy,
If you're planning on using Hibernate in any future projects, I'd highlyl recommend the hibernate eclipse plugin that lets you code in hql and see the sql output.
I've found that that helped me a lot.
best of luck,
Andy,
You keep referring to *my* and *this* application.
Can you give us a bit more background on the requirements and scalability that you are trying to achieve? I think this may put things in perspective.
The reply you got from the Hibernate forums doesn't surprise me, sadly. If I were starting a project from scratch, I would avoid using Hibernate just because of the antagonistic attitude towards users struggling to understand the technology. My company has been using Hibernate for years and most of us understand it pretty thoroughly, but when issues come up many of the developers still refuse to post questions because of the type of response they feel that they are likely to get based on past experience. I have a thick skin, so I'll often post for them.
This is the Hibernate culture that Gavin created around his project, and is now shared by many of the people who actively participate. If YOU understand a concept thoroughly and someone else doesn't, don't mentor them so that they too can understand it. Belittle them and point out how often the question has been asked before (though never actually point to where it has been answered). All this is IMHO, of course, based on the experiences I and others have had.
BTW, your post failed to point out a few places where Hibernate really shines over hand-crafted SQL: supporting multiple databases, and making maintenance much easier. Not important for your application, perhaps, but very useful in a lot of situations.
I was tired of writing the same sql CRUD queries again and again: insert into myobject ... / select ... from myobject/ update myobject ... / delete from myobject... with all the error-prone repetitions, different ways of naming and handling foreing keys/relations between objects, being TOO scared to change an attribute name because of all the hassle that comes form it...
I was too lazy to learn Hibernate and fill yet-another-xml-config-file. So I created my own API, I called it AutoDAOs.
AutoDAOs are created by passing them the class of the POJO to make persistent. They analize the POJO and make all those repetitive CRUD queries for me. Should I change an attribute name? just alter the POJO and (rebuild the table/alter the table) the CRUD queries are not affected.
Then I had to build AutoReports, arbitrary queries you run defined in static or dynamic SQL that return a list of objects. Those objects can be the POJOs managed by the AutoDAOs or just an arbitrary combination of attributes of a bunch of AutoDAOs' POJOs.
Best of both worlds?
Post a Comment
<< Home