[java] What Java ORM do you prefer, and why?

It's a pretty open ended question. I'll be starting out a new project and am looking at different ORMs to integrate with database access.

Do you have any favorites? Are there any you would advise staying clear of?

This question is related to java orm

The answer is


I have stopped using ORMs.

The reason is not any great flaw in the concept. Hibernate works well. Instead, I have found that queries have low overhead and I can fit lots of complex logic into large SQL queries, and shift a lot of my processing into the database.

So consider just using the JDBC package.


Hibernate, because it:

  • is stable - being around for so many years, it lacks any major problems
  • dictates the standards in the ORM field
  • implements the standard (JPA), in addition to dictating it.
  • has tons of information about it on the Internet. There are many tutorials, common problem solutions, etc
  • is powerful - you can translate a very complex object model into a relational model.
  • it has support for any major and medium RDBMS
  • is easy to work with, once you learn it well

A few points on why (and when) to use ORM:

  • you work with objects in your system (if your system has been designed well). Even if using JDBC, you will end up making some translation layer, so that you transfer your data to your objects. But my bets are that hibernate is better at translation than any custom-made solution.
  • it doesn't deprive you of control. You can control things in very small details, and if the API doesn't have some remote feature - execute a native query and you have it.
  • any medium-sized or bigger system can't afford having one ton of queries (be it at one place or scattered across), if it aims to be maintainable
  • if performance isn't critical. Hibernate adds performance overhead, which in some cases can't be ignored.

I would recommend using MyBatis. It is a thin layer on top of JDBC, it is very easy to map objects to tables and still use plain SQL, everything is under your control.


None, because having an ORM takes too much control away with small benefits. The time savings gained are easily blown away when you have to debug abnormalities resulting from the use of the ORM. Furthermore, ORMs discourage developers from learning SQL and how relational databases work and using this for their benefit.


I would recommend using MyBatis. It is a thin layer on top of JDBC, it is very easy to map objects to tables and still use plain SQL, everything is under your control.


While I share the concerns regarding Java replacements for free-form SQL queries, I really do think people criticizing ORM are doing so because of a generally poor application design.

True OOD is driven by classes and relationships, and ORM gives you consistent mapping of different relationship types and objects. If you use an ORM tool and end up coding query expressions in whatever query language the ORM framework supports (including, but not limited to Java expression trees, query methods, OQL etc.), you are definitely doing something wrong, i.e. your class model most likely doesn't support your requirements in the way it should. A clean application design doesn't really need queries on the application level. I've been refactoring many projects people started out using an ORM framework in the same way as they were used to embed SQL string constants in their code, and in the end everyone was suprised about how simple and maintainable the whole application gets once you match up your class model with the usage model. Granted, for things like search functionality etc. you need a query language, but even then queries are so much constrained that creating an even complex VIEW and mapping that to a read-only persistent class is much nicer to maintain and look at than building expressions in some query language in the code of your application. The VIEW approach also leverages database capabilities and, via materialization, can be much better performance-wise than any hand-written SQL in your Java source. So, I don't see any reason for a non-trivial application NOT to use ORM.


SimpleORM, because it is straight-forward and no-magic. It defines all meta data structures in Java code and is very flexible.

SimpleORM provides similar functionality to Hibernate by mapping data in a relational database to Java objects in memory. Queries can be specified in terms of Java objects, object identity is aligned with database keys, relationships between objects are maintained and modified objects are automatically flushed to the database with optimistic locks.

But unlike Hibernate, SimpleORM uses a very simple object structure and architecture that avoids the need for complex parsing, byte code processing etc. SimpleORM is small and transparent, packaged in two jars of just 79K and 52K in size, with only one small and optional dependency (Slf4j). (Hibernate is over 2400K plus about 2000K of dependent Jars.) This makes SimpleORM easy to understand and so greatly reduces technical risk.


I have stopped using ORMs.

The reason is not any great flaw in the concept. Hibernate works well. Instead, I have found that queries have low overhead and I can fit lots of complex logic into large SQL queries, and shift a lot of my processing into the database.

So consider just using the JDBC package.


I had a really good experience with Avaje Ebean when I was writing a medium sized JavaSE application.

It uses standard JPA annotations to define entities, but exposes a much simpler API (No EntityManager or any of that attached/detached entities crap). It also lets you easily use SQL queries or event plain JDBC calls when necessary.

It also has a very nice fluid and type-safe API for queries. You can write things like:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

Hibernate, because it's basically the defacto standard in Java and was one of the driving forces in the creation of the JPA. It's got excellent support in Spring, and almost every Java framework supports it. Finally, GORM is a really cool wrapper around it doing dynamic finders and so on using Groovy.

It's even been ported to .NET (NHibernate) so you can use it there too.


None, because having an ORM takes too much control away with small benefits. The time savings gained are easily blown away when you have to debug abnormalities resulting from the use of the ORM. Furthermore, ORMs discourage developers from learning SQL and how relational databases work and using this for their benefit.


Hibernate, because it's basically the defacto standard in Java and was one of the driving forces in the creation of the JPA. It's got excellent support in Spring, and almost every Java framework supports it. Finally, GORM is a really cool wrapper around it doing dynamic finders and so on using Groovy.

It's even been ported to .NET (NHibernate) so you can use it there too.


SimpleORM, because it is straight-forward and no-magic. It defines all meta data structures in Java code and is very flexible.

SimpleORM provides similar functionality to Hibernate by mapping data in a relational database to Java objects in memory. Queries can be specified in terms of Java objects, object identity is aligned with database keys, relationships between objects are maintained and modified objects are automatically flushed to the database with optimistic locks.

But unlike Hibernate, SimpleORM uses a very simple object structure and architecture that avoids the need for complex parsing, byte code processing etc. SimpleORM is small and transparent, packaged in two jars of just 79K and 52K in size, with only one small and optional dependency (Slf4j). (Hibernate is over 2400K plus about 2000K of dependent Jars.) This makes SimpleORM easy to understand and so greatly reduces technical risk.


Many ORM's are great, you need to know why you want to add abstraction on top of JDBC. I can recommend http://www.jooq.org to you (disclaimer: I'm the creator of jOOQ, so this answer is biased). jOOQ embraces the following paradigm:

  • SQL is a good thing. Many things can be expressed quite nicely in SQL. There is no need for complete abstraction of SQL.
  • The relational data model is a good thing. It has proven the best data model for the last 40 years. There is no need for XML databases or truly object oriented data models. Instead, your company runs several instances of Oracle, MySQL, MSSQL, DB2 or any other RDBMS.
  • SQL has a structure and syntax. It should not be expressed using "low-level" String concatenation in JDBC - or "high-level" String concatenation in HQL - both of which are prone to hold syntax errors.
  • Variable binding tends to be very complex when dealing with major queries. THAT is something that should be abstracted.
  • POJO's are great when writing Java code manipulating database data.
  • POJO's are a pain to write and maintain manually. Code generation is the way to go. You will have compile-safe queries including datatype-safety.
  • The database comes first. While the application on top of your database may change over time, the database itself is probably going to last longer.
  • Yes, you do have stored procedures and user defined types (UDT's) in your legacy database. Your database-tool should support that.

There are many other good ORM's. Especially Hibernate or iBATIS have a great community. But if you're looking for an intuitive, simple one, I'll say give jOOQ a try. You'll love it! :-)

Check out this example SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

And how it can be expressed in jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

While I share the concerns regarding Java replacements for free-form SQL queries, I really do think people criticizing ORM are doing so because of a generally poor application design.

True OOD is driven by classes and relationships, and ORM gives you consistent mapping of different relationship types and objects. If you use an ORM tool and end up coding query expressions in whatever query language the ORM framework supports (including, but not limited to Java expression trees, query methods, OQL etc.), you are definitely doing something wrong, i.e. your class model most likely doesn't support your requirements in the way it should. A clean application design doesn't really need queries on the application level. I've been refactoring many projects people started out using an ORM framework in the same way as they were used to embed SQL string constants in their code, and in the end everyone was suprised about how simple and maintainable the whole application gets once you match up your class model with the usage model. Granted, for things like search functionality etc. you need a query language, but even then queries are so much constrained that creating an even complex VIEW and mapping that to a read-only persistent class is much nicer to maintain and look at than building expressions in some query language in the code of your application. The VIEW approach also leverages database capabilities and, via materialization, can be much better performance-wise than any hand-written SQL in your Java source. So, I don't see any reason for a non-trivial application NOT to use ORM.


SimpleORM, because it is straight-forward and no-magic. It defines all meta data structures in Java code and is very flexible.

SimpleORM provides similar functionality to Hibernate by mapping data in a relational database to Java objects in memory. Queries can be specified in terms of Java objects, object identity is aligned with database keys, relationships between objects are maintained and modified objects are automatically flushed to the database with optimistic locks.

But unlike Hibernate, SimpleORM uses a very simple object structure and architecture that avoids the need for complex parsing, byte code processing etc. SimpleORM is small and transparent, packaged in two jars of just 79K and 52K in size, with only one small and optional dependency (Slf4j). (Hibernate is over 2400K plus about 2000K of dependent Jars.) This makes SimpleORM easy to understand and so greatly reduces technical risk.


Eclipse Link, for many reasons, but notably I feel like it has less bloat than other main stream solutions (at least less in-your-face bloat).

Oh and Eclipse Link has been chosen to be the reference implementation for JPA 2.0


Many ORM's are great, you need to know why you want to add abstraction on top of JDBC. I can recommend http://www.jooq.org to you (disclaimer: I'm the creator of jOOQ, so this answer is biased). jOOQ embraces the following paradigm:

  • SQL is a good thing. Many things can be expressed quite nicely in SQL. There is no need for complete abstraction of SQL.
  • The relational data model is a good thing. It has proven the best data model for the last 40 years. There is no need for XML databases or truly object oriented data models. Instead, your company runs several instances of Oracle, MySQL, MSSQL, DB2 or any other RDBMS.
  • SQL has a structure and syntax. It should not be expressed using "low-level" String concatenation in JDBC - or "high-level" String concatenation in HQL - both of which are prone to hold syntax errors.
  • Variable binding tends to be very complex when dealing with major queries. THAT is something that should be abstracted.
  • POJO's are great when writing Java code manipulating database data.
  • POJO's are a pain to write and maintain manually. Code generation is the way to go. You will have compile-safe queries including datatype-safety.
  • The database comes first. While the application on top of your database may change over time, the database itself is probably going to last longer.
  • Yes, you do have stored procedures and user defined types (UDT's) in your legacy database. Your database-tool should support that.

There are many other good ORM's. Especially Hibernate or iBATIS have a great community. But if you're looking for an intuitive, simple one, I'll say give jOOQ a try. You'll love it! :-)

Check out this example SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

And how it can be expressed in jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

Eclipse Link, for many reasons, but notably I feel like it has less bloat than other main stream solutions (at least less in-your-face bloat).

Oh and Eclipse Link has been chosen to be the reference implementation for JPA 2.0


Hibernate, because it's basically the defacto standard in Java and was one of the driving forces in the creation of the JPA. It's got excellent support in Spring, and almost every Java framework supports it. Finally, GORM is a really cool wrapper around it doing dynamic finders and so on using Groovy.

It's even been ported to .NET (NHibernate) so you can use it there too.


I had a really good experience with Avaje Ebean when I was writing a medium sized JavaSE application.

It uses standard JPA annotations to define entities, but exposes a much simpler API (No EntityManager or any of that attached/detached entities crap). It also lets you easily use SQL queries or event plain JDBC calls when necessary.

It also has a very nice fluid and type-safe API for queries. You can write things like:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

SimpleORM, because it is straight-forward and no-magic. It defines all meta data structures in Java code and is very flexible.

SimpleORM provides similar functionality to Hibernate by mapping data in a relational database to Java objects in memory. Queries can be specified in terms of Java objects, object identity is aligned with database keys, relationships between objects are maintained and modified objects are automatically flushed to the database with optimistic locks.

But unlike Hibernate, SimpleORM uses a very simple object structure and architecture that avoids the need for complex parsing, byte code processing etc. SimpleORM is small and transparent, packaged in two jars of just 79K and 52K in size, with only one small and optional dependency (Slf4j). (Hibernate is over 2400K plus about 2000K of dependent Jars.) This makes SimpleORM easy to understand and so greatly reduces technical risk.