What is the difference between CrudRepository and JpaRepository

A380 Cockpit — From Andrés Dallimonti

1. Acronym

  • CRUD — Create Retrieve Update Delete operation
  • JPA — Java Persistence Api
  • API — Application Program Interface
  • IDE — Integrated Development Environment

2. Objective

Explain the difference between the interfaces CrudRepository and JpaRepository.

3. CrudRepository and JpaRepository

To explain the difference let’s see the diagrams of each one.

CrudRepository diagram
JpaRepository diagram

4. Hands on

To make this article more interesting, let’s see a project that implements both interfaces and creates one Entity to store a Post in the simplest way.

4.1. Project

Below there is a project snapshot, find below the picture what each part does

Project structure

4.2. Class diagram

The diagram below shows the relationship between the entity and the repositories.

Class diagram
package com.costa.luiz.twitter.model;

import lombok.*;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.time.ZonedDateTime;
import java.util.UUID;

@Entity
@Table(name = "posts")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@ToString
@NamedQuery(name = "Post.findAllByUserAndPost",
query = "select post from Post post where post.user = ?1 and post.content like CONCAT('%',?2,'%')")
public class Post {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
private UUID id;
private String user;
private String content;
@Column(name = "created_at")
private ZonedDateTime createdAt;

}
package com.costa.luiz.twitter.model;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.time.ZonedDateTime;
import java.util.List;

@Repository
public interface PostCrudRepository extends CrudRepository<Post, String> {

List<Post> findAllByUser(String user);
List<Post> findAllByCreatedAtBetween(ZonedDateTime start, ZonedDateTime end);
List<Post> findAllByUserContains(String user);

//NamedQuery
List<Post> findAllByUserAndPost(String user, String post);

//Native Query
@Query(value = "SELECT count(1) FROM posts p WHERE lower(p.content) like CONCAT('%',?1,'%')", nativeQuery = true)
Long countPostContentWithContentLowerCase(String content);

}
package com.costa.luiz.twitter.model;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PostJpaRepository extends JpaRepository<Post, String> {
}

5. Tests

First of all, it is good practice to define a scenario 😉. For all tests, will be used the following configuration: application.yml, schema.sql, and data.sql

application.yml
schema.sql
data.sql

5.1. CrudRepository

Important to remember ❕Since JpaRepository extends CrudRepository, all the methods/test are valid to both.

Retrieve all by user
Retrieve all by user contains word
Retrieve all — NamedQuery
Count all — Native query
Retrieve all between dates

5.2. JpaRepository

Now is where the difference emerges. The first one is the method deleteAllInBatch where Spring will delete all and clean the first level cache, paying attention to not have side effects in this kind of operation.

Delete all in batch
Find all — using PageRequest
Find all — using Sort

6. Code

The complete code is available in my GitHub.

7. Run locally

To run this project locally you need the following softwares:

  • Java 11
  • Maven

7.1. Compile

mvn clean package -DskipTests

Generate the package

7.2. Run the app

java -jar target/crud_vs_jpa-0.0.1-SNAPSHOT.jar

Application started and Menu
UI via Console

8. Conclusion

It’s clear to me the benefit to have a pageable query, delete by batch and so on. Apart from the pageable query, when the project needs to flush the data either by performance problems or by database issues is a good point. In my articles from now on, I’ll adopt the JpaRepository 🙌.

9. References

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Luiz Gustavo De O. Costa

Luiz Gustavo De O. Costa

132 Followers

Hey friend!! I’m Luiz Gustavo, a Java developer and I’m here to learn and write about Java, tests and good practices