What is a JPA implementation?

I'm getting started with JPA, and I'm confused as to what exactly the JPA implementation(EclipseLink, TopLink, Hibernate, etc.) does.

I understand the theoretical role of JPA, but what is the purpose of the various implementations? Are there significant differences between these choices, as there is with say, DB connectors/drivers? Which is the best one for a beginner?

I'll probably go with EclipseLink because that is what most of the literature I've read uses.


JPA

JPA is just an API (hence Java Persistence API) that requires an implementation to use.

An analogy would be using JDBC. JDBC is an API for accessing databases, but you need an implementation (a driver jar file) to be able to connect to a database. On its own, without a driver, you cannot do anything with a database.

With JPA, as I said, you need an implementation, a set of classes that lie "below" JPA, and such an implementation will do what you want.

Your application uses the JPA API (this wording is a bit cubersome, but I hope you get the idea), which then communicates with the underlying implementation.

Popular implementations include Hibernate, EclipseLink, OpenJPA and others.

Every one of them implement the JPA API, so if you use only JPA, every implementation should act the same.

But! The functionality provided by these implementations might go beyond the standard JPA API.

If you want to use this particular functionality, you will have to use vendor specific API that will not be compatible with others.

For example, even though JPA defines the @Id annotation with ID generation options, when using Hibernate, you can use also @org.hibernate.annotations.GenericGenerator for Hibernate specific generation strategies.

Using this annotation will not work unless you're using Hibernate as the underlying implementation.

The bottom line is: JPA is the "least common denominator" which every vendor implements, and every implementation might have some more advanced features that aren't standard.

If you want your application to be portable, use only JPA. If you are sure you won't change your mind later on and switch implementations, use JPA + vendor specific features.


It's the same as Java, it has a specification (Java SE, Java EE) and implementation, most people use the reference implementation (By Sun / Oracle) which is a blueprint for others to make their own "better" and "advanced" implementation of the specification (APIs, Interfaces and documentation / JavaDoc if you need a one word definition, although it is much more than that)

So the Java / JDK you are most likely using is just an implementation (that is very popular). There are many more implementations out there, some have more Garbage Collection configuration options, some claim to be faster, and some are just not worth using.

So the implementation basically does everything, it has the code, where the JPA is an API (implied by it's name, Java Persistance API) e.g. again, more about interfaces and documentation than real implentation of the interface.

Think of it as the abstact class that Hibernate's JPA implementation / EclipseLink extends / implements

Regarding JPA, as opposed to Hibernate which has a single implementation, the idea is to decouple the interface from the implementation, so that the "best" implementation will win and that everyone can participate in the game, not just the interface creator.

This allows for instance for Google App Engine to support JPA, as it just needs to follow an API (DataNucleus is the implementation) if it has to use Hibernate, it would have required to modify the Hiberanate release to support Google's Big Table format (the fact that JPA in GAE is not that great is another story)


JPA itself is just a specification, not a product; it cannot perform persistence or anything else by itself. JPA is just a set of interfaces, and requires an implementation. There are open-source and commercial JPA implementations to choose from and any Java EE 5 application server should provide support for its use. JPA also requires a database to persist to.


The Java Persistence API (JPA) is a Java programming language application programming interface specification that describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition. The Java Persistence API originated as part of the work of the JSR 220 Expert Group of the Java Community Process. JPA 2.0 was the work of the JSR 317 Expert Group.

So, JPA provides set of interfaces which must be implemented. There are always reference implementations available for language specifications , in this case EclipseLink is the reference implementation.

Hibernate on the other hand, does implement JPA specification but it also has it's own native API.

For Example :

Say you designed an Authentication specification which contains only one interface :

public interface AccessAuthenticator {
    public boolean verifyAccess(String username,String saltedPassword);
}

Now this specification contains only one interface and one single method.

In order to use this specification(more precisely the verifyAccess( ) method) you must have an implementation.

There can be many implementations for this spec. for example, some organization may provide it's implementation for authentication to it's own servers. you must have that implementation in order to connect to the organizations server (There may be some native API involved).

One more aspect of providing a specification is that you don't actually use the concrete implementation of anything , so today say you are using hibernate to connect to your database but tomorrow some better ORM comes in picture that implements JPA spec, then all you need to do is change the dependency in your project (in simple words replace the implementation JAR file/Edit the pom file).