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"?
Spring Data JPA is not a JPA provider, it is a library/framework that adds an extra layer of abstraction on the top of our JPA provider line Hibernate.
Speaking precisely, Spring Data JPA is an add-on for JPA. It provides a framework that works with JPA and provides a complete abstraction over the Data Access Layer. Spring Data JPA brings in the concept of JPA Repositories, a set of Interfaces that defines query methods.
The implementation of JPA specifications is provided by many JPA providers, such as Hibernate, Toplink, iBatis, OpenJPA, etc.
Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.
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:
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.).
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With