How Do You Access Your Relational Data from Java?
The Java language and platform offers a vast range of options when it comes to working with relational data, from raw JDBC to fully blown Object/Relational mapping (ORM) tools. Of these, the widely used ORM tools in particular have attracted a large and growing number of high profile critics. Clojure creator Rich Hickey, for example, has repeatedly argued that ORM tools are complex ("ORM==OMG. You can't even begin to talk about how bad it is." - about 40 mins in).
Others disagree. On the back of attending QCon London 2012, where a number of people observed the ORM antagonism, Martin Fowler, wrote:
While I was at the QCon conference in London a couple of months ago, it seemed that every talk included some snarky remarks about Object/Relational mapping (ORM) tools. I guess I should read the conference emails sent to speakers more carefully, doubtless there was something in there telling us all to heap scorn upon ORMs at least once every 45 minutes. But as you can tell, I want to push back a bit against this ORM hate - because I think a lot of it is unwarranted.
The charges against them can be summarized in that they are complex, and provide only a leaky abstraction over a relational data store. Their complexity implies a grueling learning curve and often systems using an ORM perform badly - often due to naive interactions with the underlying database.
There is a lot of truth to these charges, but such charges miss a vital piece of context. The object/relational mapping problem is hard. Essentially what you are doing is synchronizing between two quite different representations of data, one in the relational database, and the other in-memory.
Given this background we're interested in what tools you are currently using, or are planning to use, to work with relational data in systems you build, and also how useful or relevant you feel they are.
There is some overlap. So for example if you use JPA with Hibernate as the provider you'd choose ORM Tool, JPA, Hibernate. Or if you are using JDBC Prepared Statements and returning results using RowSetDynaClass you'd select JDBC - Prepared Statements and Apache BeanUtils RowSetDynaClass. We're also very interested in your comments. Do you agree with the assertion that ORM's have significant weaknesses? Also, there are a lot of options: if your tool of choice is not on the list then again let us know in the comments
- ActiveJDBC: Java implementation of Active record pattern, inspired by Ruby on Rails.
- Apache BeanUtils RowSetDynaClass: Lightweight library that creates an in-memory collection of DynaBeans representing the results of an SQL query. Once the DynaClass instance has been created, the JDBC ResultSet and Statement on which it is based can be closed, and the underlying Connection can be returned to its connection pool (if you are using one).
- DataNucleus: Open source JDO and JPA implementation. Formerly known as JPOX.
- EclipseLink: Eclipse persistence platform.
- EJB: A server-side model that encapsulates the business logic of an application.
- Enterprise Objects Framework: Mac OS X/Java, part of Apple WebObjects.
- Hibernate: Hibernate is an object-relational mapping (ORM) library for the Java language, providing a framework for mapping an object-oriented domain model to a traditional relational database. Versions 3.2 and later provide an implementation for the Java Persistence API.
- Java Object Oriented Querying: Commonly known as jOOQ, is a light database-mapping software library in Java that implements the active record pattern. Its purpose is to be both relational and object oriented, by providing a domain-specific language to construct queries from classes generated from a database schema.
- JDBC - CallableStatements: Calling Stored Procedures on the database.
- JDBC - Prepared Statements: The statement is cached and then the execution path is pre-determined on the database server allowing it to be executed multiple times in an efficient manner.
- JDBC - Statement: Sent to the database server each time.
- JDO: Java Data Objects (JDO) is a specification of Java object persistence.
- JPA: Standard Java programming language specification which describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition.
- MyBatis: MyBatis is a Java persistence framework that couples objects with stored procedures or SQL statements using an XML descriptor or annotations. It differs from a full ORM in that it does not map Java objects to database tables but instead transfers to SQL statements.
- An ORM tool with native queries: Pick this option if you use native queries exclusively within your ORM tool of choice.
- An ORM tool: Specific examples of common ORM tools are provided, but if you use an ORM tool directly select this.
- Spring Data JDBC Extensions: Provides additional support for vendor specific JDBC extensions as well as new approaches to working with JDBC, like Querydsl.
- Spring Data JPA: Part of the larger Spring Data family for working with JPA based repositories. This module deals with support for JPA based data access layers.
- Other Spring Data: If you are using a non-relational datastore with Spring data - for example Spring Data MongoDB, Spring Data Neo4J, Spring Data Redis, Spring for Hadoop, Spring Data GemFire or Spring Data REST this is the option you want.
TopLink: Oracle's ORM tool. TopLink Essentials is a reference implementation of the EJB 3.0 Java Persistence API (JPA).
jOOQ is missing
Gilberto C Andrade
Re: jOOQ is missing
Re: jOOQ is missing
It's just a difficult relationship
Jacques Le Roux
Interesting article on ORM impedence mismatch issue by Uncle Bob Martin
Querydsl is missing
Misleading categories, missing entries
Obviously JDO, JPA are just specs and not the implementation so misleading to include those. So what if someone puts Hibernate, JPA ... how does that compare to just DataNucleus ? because with DataNucleus they'd have to be using either JDO or JPA and your categorisation is inadequate to express such things ... hence far easier just to put the persistence implementation
Re: Misleading categories, missing entries
Thanks for your comments.
In terms of missing options I'm aware that we haven't got everything in (there are so many options it would have been practically impossible) - but I did try to choose the most widely used examples. This, of course, is also why the comments are so useful - a follow up survey might include some more of the options that people call out here. In the case of Kodo I 'd expect someone to put "JDO" and note it in the comments, same with OpenJPA really.
I'm not quite sure I follow your argument with regards your second point. Are you saying that DataNucleus is likely to be under-represented because people might only put JPA or JDO when they are using your product? If anything I'd expect it to go the other way round, though my intention would be for someone to pick as an example DataNucleus and JDO. Same thing applies for using JPA with Hibernate as the underlying provider of course.
Re: Misleading categories, missing entries
The problem is the problem... quite so!
EXACTLY! Not to diss ORM, but there shouldn't be a relational database underneath an "ORM layer" in the first place. It is confusing for the developer and designer (is she/he dealing with objects or relations? What to optimize for? Do you REALLY want to access the relations later in freeform combat with SQL? No you don't.) The fact that this uneasy union is in need of a marriage consultant is a consequence of the death of the object-oriented database of the 90s. Where did it go? Too many disparate approaches, no mathematical model, no clear foundations and missed the FLOSS train. Or maybe the hardware war not affordable enough.
And what happened to Datalog? Why the terrible, evil hegemony of SQL? I would even prefer Tutorial D.