How does Spring Data (JPA) relate to JPA persistence providers?

java, jpa, spring, spring-data, spring-data-jpa

Solution

The Spring Data project in general is an umbrella project with the following mission statement:

… provide a familiar and consistent Spring-based programming model while retaining store-specific features and capabilities.

So we approach the persistence space in general not only relational data access through JPA. The important piece here is two fold:

- Programming model instead of generic API

- Support for store specific features

As the data access space is so diverse these days, trying to approach all of the stores with a single unifying API is doomed to fail. You'd end up with a least common denominator that hides away the store specific parts - in times where you selectively choose a particular store because of it's specifics. Abstracting those away totally subverts this. Especially trying to use JPA is wrong in our opinion as it's deeply tied to relational concepts (`@Table`, joins, transactions) by definition.

Still, you don't want to work with completely different APIs, don't wanna be lost in store differences if you work with multiple ones or switch from one project to another. Spring has traditionally helped in that regard by embracing a consistent programming model, that features abstractions that work the same way but are still specific to a particular technology. For example, JDBC and JMS are completely different technologies. Spring offers both a `JdbcTemplate` as well as a `JmsTemplate` that cover the same responsibilities (resource management and exception translation) and lower the learning curve when moving from working with JDBC to JMS or vice versa.

Spring Data picks up on that by exposing store-specific functionality through abstractions that Spring developers know. I already mentioned the template, but that also includes general configuration mechanisms (XML namespaces, using DI and AOP etc.).

Repositories

The very top layer of this programming model is the repository abstraction. In its core, it significantly simplifies the development of data access layers by letting you avoid to write more implementation code than strictly necessary. It provides CRUD functionality out of the box, pagination as well as declarative query methods.

Assume a `Customer` domain class. Enabling persistence for it is just a matter of declaring a repository interface like this:

interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {

  List<Customer> findByLastnameContaining(String lastname);
}

Now it's a matter of configuration (and domain class mapping) to be able to create an instance of this interface and use it from a client. `PagingAndSortingRepository` includes basic CRUD functionality as well as stuff like `Page<Customer> findAll(Pageable pageable)` (so page-by-page access). As you can see, we also support a query derivation mechanism to avoid needing to write any implementation code for simply queries. For more complex ones, we allow the manual declaration (e.g. using `@Query` on the method) or even the manual implementation if necessary.

A neat side-effect here is, that by a flip-switch in the configuration you could use the same repository interface to persist `Customer` instances into a MongoDB. That doesn't mean we recommend to blindly move from one store to another as the stores usually require the data model to be adapted to work efficiently. However it allows developers to quickly switch between projects working with different stores as the repositories just work the same way (implementing the programming model over common API approach).

JPA specifics

Spring Data JPA is actually a thin layer implementing the repository abstraction plus a few other bells and whistles. So we're not replacing persistence providers but actually leverage them through the API, even mitigating some of the quirks and differences between individual JPA providers.

Problem

I'm trying to wrap my head around JPA and have learned quite a bit. JPA is a java specification and providers implement this spec. I Understand that part. What I don't understand is how Spring Data comes into the picture. Is Spring Data also a provider like Hibernate or OpenJPA? If not, what is it? How does Spring Data "make things easier"?

Original source