Spring Data JPA

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

Spring Data JPA is a Spring Data project that assists with implementing JPA-based repositories, which persist data in relational databases. The approach involves writing the repository interface, including custom finder methods, and Spring will provide the implementation automatically.

Spring Persistence Concepts

Spring Persistence Concepts

Spring Boot Support

To add support for Spring Data JPA to a Spring Boot project, add the following starter dependency:

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
}

This starter dependency also transitively includes Hibernate as the JPA implementation.

Spring Data JPA needs a database to work with. This is how to add H2 support:

dependencies {
    runtimeOnly('com.h2database:h2')
}

Adding Persistence to an Application with Spring Data JPA

Annotate Domain Objects with @Entity

Annotate your domain objects that require persistence with @Entity and designate their primary key field with @Id and optionally with @GeneratedValue. JPA requires each entity class to expose a no-argument constructor, which can be coded manually, or it can be generated with Lombok's @NoArgConstructor:

@NoArgConstructor(access=AccessLevel.PRIVATE, force=true)

Define Relationships between Entities

@ManyToMany, etc.

Declare the JPA Repositories

Entities are built, managed and exposed to the application by JPA repositories. JPA repositories should be explicitly declared in the application. A Spring Data JPA repository is the embodiment of the Spring repository concept concept, which, similarly to a JdbcTemplate-based repository, conceals low-level data access details from the application while exposing Entities to the application. With JdbcTemplate-based repositories the developers need to explicitly declare and implement the methods that should be exposed by the repository, such as findOne(...), findAll() and save(...). With Spring Data JPA repositories, it is sufficient to extend the CrudRepository interface that comes with essential methods.

public interface IngredientRepository extends CrudRepository<Ingredient, String> {
}

TODO

CrudRepository

org.springframework.data.repository.CrudRepository JavaDoc
public interface CrudRepository<T, ID> extends Repository<T, ID> {

	/**
	 * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
	 * entity instance completely.
	 * 
	 * @param entity must not be {@literal null}.
	 * @return the saved entity will never be {@literal null}.
	 */
	<S extends T> S save(S entity);

	/**
	 * Saves all given entities.
	 * 
	 * @param entities must not be {@literal null}.
	 * @return the saved entities will never be {@literal null}.
	 * @throws IllegalArgumentException in case the given entity is {@literal null}.
	 */
	<S extends T> Iterable<S> saveAll(Iterable<S> entities);

	/**
	 * Retrieves an entity by its id.
	 * 
	 * @param id must not be {@literal null}.
	 * @return the entity with the given id or {@literal Optional#empty()} if none found
	 * @throws IllegalArgumentException if {@code id} is {@literal null}.
	 */
	Optional<T> findById(ID id);

	/**
	 * Returns whether an entity with the given id exists.
	 * 
	 * @param id must not be {@literal null}.
	 * @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
	 * @throws IllegalArgumentException if {@code id} is {@literal null}.
	 */
	boolean existsById(ID id);

	/**
	 * Returns all instances of the type.
	 * 
	 * @return all entities
	 */
	Iterable<T> findAll();

	/**
	 * Returns all instances of the type with the given IDs.
	 * 
	 * @param ids
	 * @return
	 */
	Iterable<T> findAllById(Iterable<ID> ids);

	/**
	 * Returns the number of entities available.
	 * 
	 * @return the number of entities
	 */
	long count();

	/**
	 * Deletes the entity with the given id.
	 * 
	 * @param id must not be {@literal null}.
	 * @throws IllegalArgumentException in case the given {@code id} is {@literal null}
	 */
	void deleteById(ID id);

	/**
	 * Deletes a given entity.
	 * 
	 * @param entity
	 * @throws IllegalArgumentException in case the given entity is {@literal null}.
	 */
	void delete(T entity);

	/**
	 * Deletes the given entities.
	 * 
	 * @param entities
	 * @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}.
	 */
	void deleteAll(Iterable<? extends T> entities);

	/**
	 * Deletes all entities managed by the repository.
	 */
	void deleteAll();
}

TODO

  • How to tell that a JPA repository should use a specific database. How is that configured?
  • @EnableJpaRepositories(basePackages = "com.example.dev.myproject.driver.repo")