Spring Data JDBC / Spring Data JPA vs Hibernate
Solution 1:
As @Naros said, the question as it is currently in the title doesn't really work. It seems we should really look at 4 options and mostly list the pros of each approach, the cons are the absence of the pros of the other:
JDBC without Spring Data
You get 100% fine-grained control over what is happening. Nothing gets generated or injected by a framework. This might sound like a con, but if you have tried to tweak mappings and configurations to get some JPA implementation to do what you could trivially write down in java and SQL, you'll understand that this can be a big pro.
You don't have to learn JPA, nor Spring Data. I personally think Spring Data is easy, but I'm biased (see my Profile). But JPA is most certainly challenging, once you leave the area of trivial entities and setup.
- no requirements how you model your domain model (JPA requires default constructors for example)
You probably want to use some library in order to cut down on boilerplate code. Take a look at:
-
JOOQ
-
MyBatis
-
Spring JdbcTemplate (usable without the rest of Spring)
-
QueryDsl
JDBC with Spring Data
You get the benefits of Spring Data, combined with those of JDBC (see above):
-
Repositories with CRUD methods out of the box.
-
Support for Aggregates. See https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates
-
Nice integration in the Spring infrastructure, for transaction handling, dependency injection, error translation, paging ...
-
It is still a really simple programming model. SQL statements happen exactly when one would expect them to happen and if you want to you can fall back to simple JDBC with or without the support of other frameworks, without breaking any abstraction.
-
Nice and easy ways to extend your repositories with query methods (you just define your interface to have a
findByLastName
method and Spring generates it for you on the fly) or@Query
annotations or custom methods. -
Support for paging
Hibernate (or some other JPA implementation) without Spring Data
JPA does a lot of things over JDBC
-
Caching (1st, 2nd level, and query cache)
-
Automated creation of instances from queries
-
Navigation between entities
-
Lazy loading
-
Dirty checking / tracking of changes to entities
With all this stuff happening it can be difficult understanding what is happening and why. Of course IFF you structure your application properly, you can just fall back on JDBC if JPA doesn't offer what you want. But I have seen it multiple times that people failed to maintain the structure required for that to work. Obviously, this is especially difficult if you don't understand properly how JPA works.
Hibernate (or some other JPA implementation) with Spring Data
I listed the benefits of Spring Data above, just perform a mental copy&paste.
Of course, this makes the complete stack even more complex. From the many questions tagged with spring-data AND hibernate it seems many developers have problems identifying which tool does what. But also from looking at these questions most describe problems with Hibernate/JPA and not Spring Data.
To wrap it up:
-
If you want/need fine-grained control use JDBC.
-
If you're going to use JPA, make sure you understand it early on.
-
If for the persistence technology you are choosing Spring Data offers a module, I would use it. It will make life easier. But again I'm biased.
Solution 2:
One problem with your question is you seem to imply that Spring Data JPA is like Hibernate and that's actually not true. Spring Data JPA is merely a spring-centric wrapper that offers springy semantics and features that wrap a JPA provider of which Hibernate is one implementation.
Ergo, you cannot use Spring Data JPA without including some JPA implementation like Hibernate.
The base question you're asking then is why use JDBC vs an ORM. In order to understand that you should take time to understand the benefits of an ORM. There are numerous articles on the internet that can give you that.
But even in an ORM driven application, there will be times where you'll have cases that you need to bypass the ORM framework and use native SQL just like you would in JDBC. Those cases are often rare, but necessary when you want to take advantage of some unsupported database feature or where you want to have ultimate control of manipulating the results, etc.
The deciding factor on which to use ultimately depends on your application's needs. But just because you elect to use an ORM framework doesn't mutually exclude the ability to execute native queries and SQL statements like you would in JDBC. Those features are still available, you just typically use those in rare cases.
Solution 3:
The thing is Spring data for jpa is an abstraction over jpa, which is an abstraction over JDBC. If offer nice features, even if jpa is usable without it. It becomes really powerful with Spring data rest.
But the more a framework does for you, the more you need to understand underlying technology. It is even more true if you use spring-data-rest. The best is to start by understanding sql (design and queries), then jpa (lazy loading, instance states, entities, embeddables, caches, queries, transaction synchronization).
Then you try spring-data-jpa and decide if it brings value to you project. For save, update, delete and find by id operations it is basically a wrapper around persist
, merge
, remove
and find
method of EntityManager
. The main advantage of Spring data JPA is the query support, but querydsl is also a nice option. In both case it requires a clear understanding of how JPA works. The first thing to do is to turn on SQL logging to see if, for a given db access, your jpa implementation execute queries that a dba would consider correct. For instance, eager loading on an entity which is not in cache results in 1+n select, you unit test will pass and problems will start in production. spring-data-jpa will not solve the problem for you.
There are many spring-data-* beside spring-data-jpa, some of them also offer mapping annotations (spring-data-cassandra for instance), which is useful when there is no object-db mapping.