An example of some complicated aspects of Spring Data JPA such as
- fetching strategies of
@OneToMany
and@ManyToMany
collections - locking strategies
- entity to DTO mapping
- JDK 11
- Docker at least 1.6.0
To build project and run all tests use command
./gradlew cleanTest test -i
- JDK 11
- Spring Boot 2.2.x
- Spring Data JPA 2.2.x
- MapStruct 1.3.1.Final
- JUnit 5
- Testcontainers
This example has a simple domain model. A book has at least one author and belongs to at least one category. A book can be rated. An average rating and a total number of ratings are tracked.
Simplified UML class diagram
Many-to-many relationship List<Author> authors
has javax.persistence.FetchType.EAGER
and many-to-many relationship Set<Category> categories
has javax.persistence.FetchType.LAZY
.
To demonstrate how different org.hibernate.annotations.FetchMode
s work
the hierarchy of book classes used:
com.example.spring.data.jpa.entity.AbstractBook
-@MappedSuperclass
com.example.spring.data.jpa.entity.Book
- no explicit@Fetch
com.example.spring.data.jpa.entity.BookWithFetchModeJoin
-@Fetch(JOIN)
com.example.spring.data.jpa.entity.BookWithFetchModeSelect
-@Fetch(SELECT)
com.example.spring.data.jpa.entity.BookWithFetchModeSubselect
-@Fetch(SUBSELECT)
com.example.spring.data.jpa.entity.BookWithBatchSize
-@BatchSize
com.example.spring.data.jpa.entity.BookWithMultipleBags
- doesn't extendAbstractBook
and hasList<Category> categories
instead of Set like inAbstractBook
and its children what leads toMultipleBagFetchException: cannot simultaneously fetch multiple bags
when both relations are fetched using join.
To demonstrate locking strategies a com.example.spring.data.jpa.entity.BookRating
class has @Version int version
field.
Actual UML class diagram
Entity-relationship diagram
- Fetching strategies
- Entity without explicit
@Fetch
-com.example.spring.data.jpa.BookRepositoryTest
CrudRepository.findById
- Query method
- Query method with
@EntityGraph
- Query method with
@EntityGraph
andPageable
- Query method with
@EntityGraph
with multiple attribute nodes (issue HHH-13740) @Query
with JPQLjoin fetch
@Query
with JPQL join fetch and distinct- Custom
@Repository
with Criteria API query - Custom
@Repository
with Criteria API query withfetch
- Custom
@Repository
with Criteria API query withfetch
anddistinct
- Mapping from entity to DTO using MapStruct
- Entity with
@Fetch(JOIN)
-com.example.spring.data.jpa.BookWithFetchModeJoinRepositoryTest
CrudRepository.findById
- Query method
- Entity with
@Fetch(SELECT)
-com.example.spring.data.jpa.BookWithFetchModeSelectRepositoryTest
CrudRepository.findById
- Query method
- Entity with
@Fetch(SUBSELECT)
-com.example.spring.data.jpa.BookWithFetchModeSubselectRepositoryTest
CrudRepository.findById
- Query method
- Entity with
@BatchSize
-com.example.spring.data.jpa.BookWithBatchSizeRepositoryTest
CrudRepository.findById
- Query method
- Entity with multiple bags (two
@ManyToMany
collections with typeList
) resulting inMultipleBagFetchException
-com.example.spring.data.jpa.BookWithMultipleBagsRepositoryTest
- Entity without explicit
- Locking strategies -
com.example.spring.data.jpa.BookRatingRepositoryTest
- Implicit optimistic lock of entity with
@Version
on modification - Explicit optimistic lock
@Lock(OPTIMISTIC)
- Explicit optimistic lock
@Lock(OPTIMISTIC_FORCE_INCREMENT)
- Explicit pessimistic write lock
@Lock(PESSIMISTIC_WRITE)
- Explicit pessimistic read lock
@Lock(PESSIMISTIC_READ)
- Implicit optimistic lock of entity with