Hibernate, iBatis, Java EE or other Java ORM tool

JavaHibernateOrmJakarta EeIbatis

Java Problem Overview


We're in the process of planning a large, enterprise application. We're focusing our efforts on evaluating hibernate after experiencing the pains of J2EE.

It looks like the new Java EE API is simpler. I've also read some good things about Hibernate and iBatis. Our team has little experience with any of the frameworks.

There are 5 main comparisong points I'd like to determine

  • Learning Curve/Ease of Use
  • Productivity
  • Maintainability/Stability
  • Performance/Scalability
  • Ease of Troubleshooting

If you were to manage a team of ~6 developers with J2EE experience which ORM tool would you use and why?

Java Solutions


Solution 1 - Java

Let me take a crack at this. First of, I've written some on this subject in Using an ORM or plain SQL?. Specifically to address your points:

Learning Curve/Ease of Use

Ibatis is about SQL. If you know SQL the learning curve for ibatis is trivial. Ibatis does some things on top of SQL such as:

  • group by;
  • discriminated types; and
  • dynamic SQL.

that you'll still need to learn but the biggest hurdle is SQL.

JPA (which includes Hibernate) on the other hand tries to distance itself from SQL and present things in an object rather than a relational way. As Joel points out however, abstractions are leaky and JPA is no exception. To do JPA you'll still need to know about relational models, SQL, performance tuning of queries and so forth.

Whereas Ibatis will simply having you apply the SQL you know or are learning, JPA will require you to know something else: how to configure it (either XML or annotations). By this I mean figuring out that foreign key relationships are a relationship (one-to-one, one-to-many or many-to-many) of some kind, the type mapping, etc.

If you know SQL I would say the barrier to learning JPA is actually higher. If you don't, it's more of a mixed result with JPA allowing you to effectively defer learning SQL for a time (but it doesn't put it off indefinitely).

With JPA once you setup your entities and their relationships then other developers can simply use them and don't need to learn everything about configuring JPA. This could be an advantage but a developer will still need to know about entity managers, transaction management, managed vs unmanaged objects and so on.

It's worth noting that JPA also has its own query language (JPA-SQL), which you will need to learn whether or not you know SQL. You will find situations where JPA-SQL just can't do things that SQL can.

Productivity

This is a hard one to judge. Personally I think I'm more productive in ibatis but I'm also really comfortable with SQL. Some will argue they're way more productive with Hibernate but this is possibly due--at least in part--to unfamiliarity with SQL.

Also the productivity with JPA is deceptive because you will occasionally come across a problem with your data model or queries that takes you a half a day to a day to solve as you turn up logging and watch what SQL your JPA provider is producing and then working out the combination of settings and calls to get it to produce something that's both correct and performant.

You just don't have this kind of problem with Ibatis because you've written the SQL yourself. You test it by running the SQL inside PL/SQL Developer, SQL Server Management Studio, Navicat for MySQL or whatever. After the query is right, all you're doing is mapping inputs and outputs.

Also I found JPA-QL to be more awkward than pure SQL. You need separate tools to just run a JPA-QL query to see the results and it's something more you have to learn. I actually found this whole part of JPA rather awkward and unwieldy although some people love it.

Maintainability/Stability

The danger with Ibatis here is proliferation meaning your dev team may just keep adding value objects and queries as they need them rather than looking for reuse whereas JPA has one entitty per table and once you have that entity, that's it. Named queries tend to go on that entity so are hard to miss. Ad-hoc queries can still be repeated but I think it's less of a potential problem.

That comes at the cost of rigidity however. Often in an application you will need bits and pieces of data from different tables. With SQL it's easy because you can write a single query (or a small number of queries) to get all that data in one hit and put it in a custom value object just for that purpose.

With JPA you are moving up that logic into your business layer. Entities are basically all or nothing. Now that's not strictly true. Various JPA providers will allow you to partially load entities and so forth but even there you're talking about the same discrete entitites. If you need data from 4 tables you either need 4 entities or you need to combine the data you want into some kind of custom value object in the business or presentation layer.

One other thing I like about ibatis is that all your SQL is external (in XML files). Some will cite this is as a disadvantage but not me. You can then find uses of a table and/or column relatively easy by searching your XML files. With SQL embedded in code (or where there is no SQL at all) it can be a lot harder to find. You can also cut and paste SQL into a database tool and run it. I can't overstate enough how many times this has been useful to me over the years.

Performance/Scalability

Here I think ibatis wins hands down. It's straight SQL and low cost. By its nature JPA simply won't be able to manage the same level of latency or throughput. Now what JPA has going for it is that latency and throughput are only rarely problems. High performance systems however do exist and will tend to disfavour more heavyweight solutions like JPA.

Plus with ibatis you can write a query that returns exactly the data you want with the exact columns that you need. Fundamentally there's no way JPA can beat (or even match) that when it's returning discrete entities.

Ease of Troubleshooting

I think this one is a win for Ibatis too. Like I mentioned above, with JPA you will sometimes spend half a day getting a query or entity produce the SQL you want or diagnosing a problem where a transaction fails because the entity manager tried to persist an unmanaged object (which could be part of a batch job where you've committed a lot of work so it might be nontrivial to find).

Both of them will fail if you try to use a table or column that doesn't exist, which is good.

Other criteria

Now you didn't mention portability as one of your requirements (meaning moving between database vendors). It's worth noting that here JPA has the advantage. The annotations are less portable than, say, Hibernate XML (eg standard JPA annotations don't have an equivalent for Hibernate's "native" ID type) but both of them are more portable than ibatis / SQL.

Also I've seen JPA / Hibernate used as a form of portable DDL, meaning you run a small Java program that creates the database schema from JPA configuration. With ibatis you'll need a script for each supported database.

The downside of portability is that JPA is, in some ways, lowest common denominator, meaning the supported behaviour is largely the common supported behaviour across a wide range of database vendors. If you want to use Oracle Analytics in ibatis, no problem. In JPA? Well, that's a problem.

Solution 2 - Java

A simplistic rule of thumb between iBatis and Hibernate is that if you want more SQL/relational view of the world, iBatis is better fit; and for more complex inheritance chain, and less direct view to SQL, Hibernate. Both are widely used and solid good frameworks. So I think both would probably work well. Perhaps read a tutorial for both, see if one sounds better than the other, and just pick one.

Of things you list, I don't think performance is very different -- bottleneck will almost invariably be the database, not framework. For other things I think different developers would prefer one or the other, i.e. there's no commonly accepted priority (for iBatis vs Hibernate).

Solution 3 - Java

Which solution you go with also is dependent on how compliant you choose (or are required) to be with the Java EE spec. JPA is "the standard" for data access in Java EE systems, so if you're particular about adhering to that, you should use it (with some caveats).

JPA is a standardization of object-relational mapping systems. As such, it does not provide an implementation, it simply defines a standardized approach. Hibernate Entity Manager is one such implementation.

Since JPA is a standard across multiple vendors and since it is still fairly new, it lacks some more esoteric functionality that is valuable in some use cases (for example, a Criteria API for generating dynamic SQL). If you go with JPA plan on situations where you'll nee to use Hibernate directly, or even JDBC directly. For situations such as this, a generic DAO pattern is very useful; you can modify this one: Generic Data Access Objects for use in JPA & JDBC quite easily.

JPA has some difficult restrictions (particularly if you're used to Hibernate), and imposes certain approaches on you that are difficult for developers who are more used to writing straight JDBC. If you are championing this as an approach, be sure to do your homework about the pros vs. cons of ORM vs. JDBC.

If you go with JPA, once you've reached the learning curve it will pay off in terms of simple development (particularly if you properly implement the abovementioned DAO pattern), but also in getting multi-tiered caching of query results. If done properly (a big "if", I know), I have seen this provide handsome benefits.

Lastly, if you have a legacy data model that you have little flexibility with, Hibernate (and JPA) will give you more headaches than maybe worth. For example:

  • If the database does not have candidate primary keys (for effective hashCode & equals implementations) you will need to do upfront analysis on which columns define a row uniquely -- maybe simple, maybe complex depending on the complexity of your schema;
  • If you're unable to add version or timestamp columns, you lose Hibernate's ability to do optimistic locking, and end up having to query before updating.

> (Added in response to first comment) > If you're lucky enough to re-design > your database, two very important > considerations if you're going to be > using an ORM: > > - Add a version number column to all relevant tables to support optimistic locking. > - During your data analysis, decide on non-nullable "alternate key" column(s) > that developers should use for hashCode() & equals(). Don't use PK columns in those > methods.

Solution 4 - Java

To add another option to the list... have a look at:

Ebean ORM (http://ebean-orm.github.io).

It's main claim would be a simpler more intuitive programming model than JPA or Hibernate. Specifically, it doesn't have a Hibernate Session or JPA EntityManager, no detached/attached objects (no merge, persist, flush), lazy loading just works.

... aka much simpler to use and understand.

You can also use your own SQL with Ebean (for queries, updates, stored procedures) and IMO it matches Ibatis in ease of use wrt using your own SQL.

If you are looking to use the ORM in Java SE then I'd suggest you check it out.

  • LGPL Licence
  • Use JPA annotations for mapping (@Entity, @OneToMany etc)
  • Session-less API (no merge, persist, flush ... save() and delete() instead)
  • "Partial Object" support
  • Large Query support (per object graph persistence context)
  • Background queries
  • Good support for batch processing
  • Automatic Query tuning (via "Autofetch")

Cheers, Rob.

Solution 5 - Java

We are currently working on a project which uses both Hibernate and ibatis. Why use hibernate ? It supports our domain model, relationships and inheritance. We have a pretty complex domain model and hiberante supports it very well. No need to worry about writing inserts, updates etc. Ibatis is used only for view. There are queries and we have view objects(similar to domain models but not domain models) which are mapped with queries. Ibatis returns the data in the view obejct you want without worrying about reading from result set , which you have to manage in Spring JDBC. Why do we that instead of using HQl or Spring JDBC ? The domain is so complex and when rendering view , we do calculations , group by and tons of native SQL functions. we do all that in query, use dynamic queries , manage conditions in ibatis and get a clean light weight object. Makes much more sense if you have to traverse down multiple layers to fetch data in hibernate So depending on your situation , you may want to use only one, both or may be none. But definitely, hibernate is not something you cannot live without.

Solution 6 - Java

Be aware that using JPA/Hibernate (and probably most other ORM solutions) in non-trivial multi-threaded applications can quickly become a real PITA because database sessions need to be confined to exactly one thread (Session objects are not thread-safe). Add lazy loading and the fact that persistent entities can belong to at most one active session...and you're in for a hell of a ride...

You might want to have a look at https://stackoverflow.com/questions/1664446/session-management-using-hibernate-in-a-multi-threaded-swing-application (or just search for 'hibernate multi-threaded').

My rule of thumb (YMMV): If the application does not lend itself to some kind of request/response cycle (like a webservice for example) , you may probably be better off using something else.

Of course, another solution would be to design the application in a way that circumvents the mentioned framework limitations. Changing an application's design so I can get framework XYZ to work leaves a bad aftertaste though.

Anyway, just my $0.02

Solution 7 - Java

I think that we should take in consideration the main reason why we're using Java (or OO).

The system has to be flexible and allow constant modifications of the specification (this happens very often in real life). Otherwise we should have programmed in C, because it's a lot faster.

I think that the best stack for web applications would be Java EE: JPA - EJB - JSF (with extended persistence context conversation scoped).

JSF also is slower than pure JSP/Servlet, but it's faster to develop.

JPA is harder to learn, but it's faster to develop (you know: RAD) and changes don't have big (error prone copy-paste) impact. Add a new column in your most used entity, and you will have to update all statements in iBatis ...

JPA doesn't work very good on all cases, but it covers most of them, and it also let you plug Native Query instead of JPQL without changing any code. But if you find yourself writing too much Native Query your project's might fit better iBatis.

And as for performance, JPA is also performant if you understand how things translate to SQL, and if you put it to do what he is best at, if you put it to do something that's not comfortable for him, it will generate too much queries. There's no magic ! You have to be aware of the generated query, not blindly hope that you can take the easy way when some complicated case might appear.

Also if developers have all the capabilities of SQL they will write too complex queries to process business logic, instead of having it in a centralized place, you will have some business logic in SQL, some in EJB. JPA should be for persisting your model, not for Business Logic.

Criteria Query is also no match for building safe nomatterhowcomplex dynamic queries.

Solution 8 - Java

If you are indeed have a greenfield project, you may use hibernate, but be aware that the learning curve is quite steep.

If you have a existing database you are much better of with iBatis, because after one day you are productive and after two more days you can know all about it.

One thing you have to consider is, that the hibernate criteria api is excellent for creating custom queries, which depending on your application, may be a good argument for it.

Solution 9 - Java

If you don't have a good object model, I don't see the benefit of Hibernate. You certainly have the "relational" in ORM, since you have a relational database, but the "object" is key. No objects, no ORM. I think a 1:1 mapping between objects and tables, without richer object behavior, does not justify ORM. Stick with JDBC or iBatis if that's your situation.

Solution 10 - Java

I'd suggest going with JPA and depending (heavily!) on the duration/scope of your project you might as well look into JPA2, for it provides some of the missing features of JPA (a very nice Query API for example).

Solution 11 - Java

Go with hibernate. Your project will definitely grow larger later on and the investment (on learning hibernate) will pay off one way or another.

Solution 12 - Java

Have you tried to answer WHY even use an ORM tool before deciding which one to use? If you have people on your team who know SQL, see stick to JDBC.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKevin WilliamsView Question on Stackoverflow
Solution 1 - JavacletusView Answer on Stackoverflow
Solution 2 - JavaStaxManView Answer on Stackoverflow
Solution 3 - JavaEdward Q. BridgesView Answer on Stackoverflow
Solution 4 - JavaRob BygraveView Answer on Stackoverflow
Solution 5 - JavavsinghView Answer on Stackoverflow
Solution 6 - JavaJavaGuyView Answer on Stackoverflow
Solution 7 - JavaCosmin CosminView Answer on Stackoverflow
Solution 8 - JavaMauliView Answer on Stackoverflow
Solution 9 - JavaduffymoView Answer on Stackoverflow
Solution 10 - JavaJoachim SauerView Answer on Stackoverflow
Solution 11 - JavacherouvimView Answer on Stackoverflow
Solution 12 - JavaYakov FainView Answer on Stackoverflow