Data JPA

(Spring Boot)

Introduction

n/a

pom.xml

    <!-- Persist data in SQL stores with Java Persistence API using Spring Data and Hibernate -->

    <dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-data-jpa</artifactId>

    </dependency>


    <!-- Fixes error: jakarta.validation.NoProviderFoundException -->

    <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-validation</artifactId>

    </dependency>

QueryByExampleExecutor interface

The interface JpaRepository exteds the interface QueryByExampleExecutor:

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>

The interface QueryByExampleExecutor add more find methods with Example as argument:

<S extends T> Optional<S> findOne(Example<S> example);

<S extends T> Iterable<S> findAll(Example<S> example);

<S extends T> Iterable<S> findAll(Example<S> example, Sort sort);

<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);

<S extends T> long count(Example<S> example);

<S extends T> boolean exists(Example<S> example);

The interface Example provides methods for accessing the probe (instance of our entity) and the ExampleMatcher:

static <T> Example<T> of(T probe)

static <T> Example<T> of(T probe, ExampleMatcher matcher)

T getProbe()

ExampleMatcher getMatcher()

default Class<T> getProbeType()

Note: Our probe and out ExampleMatcher together specify our query.


Limitations

QueryByExampleExecutor examples

Entity:

@Entity

public class Employee {

  @Id

  @GeneratedValue

  private Long id;

  private String name;

  private String dept;

}

Probe:

Employee employee = new Employee();

 employee.setName("Erika");

 Example<Employee> employeeExample = Example.of(employee);

Remark: By default, fields having null values are ignored in the underlying query,  so above Example will be equivalent to the following JPQL: 

SELECT t from Employee t where t.name = 'Erika';

Warning: As Query by Example technique relies on null values to be omitted in the query generation, we should not use primitive identity (like int, long) in our Entity (as in above example) because it will default to 0 instead of null. 

findEmployeesByName

      System.out.println("-- finding employees with name Tim --");

      Employee employee = new Employee();

      employee.setName("Tim");

      Example<Employee> employeeExample = Example.of(employee);

      //calling QueryByExampleExecutor#findAll(Example)

      Iterable<Employee> employees = repo.findAll(employeeExample);

findEmployeesByNameAndDept

      System.out.println("-- finding employees with name Jack and dept IT --");

      Employee employee = new Employee();

      employee.setName("Jack");

      employee.setDept("IT");

      Example<Employee> employeeExample = Example.of(employee);

      //calling QueryByExampleExecutor#findAll(Example)

      Iterable<Employee> employees = repo.findAll(employeeExample);


Spring Data JPA Projections

Reference article > https://www.baeldung.com/spring-data-jpa-projections

An entity class may have many projections. The reference article demonstrates using repositories with: