Spring Data Overview
Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.
Java Persistence API
In-memory data structure store
Reactive Relational Database Connectivity
Flyway & Liquibase
JPA
N+1 Query Problem
Link : Annotations Notes
Initializing a lazy relation via calling a method on a mapped relation causes an additional query. This should be avoided for performance reasons.
- Solutions
- SQL :
- JOIN
- JOIN FETCH : (JPQL)
- Eager Fetching
- Entity Graph
- Named Entity Graphs : a good solution if you will reuse the defined graph in code
- Dynamic Entity Graphs : can be the better solution if you need to define a use case specific graph
- DTO projection
- SQL :
NamedEntityGraph
Init
List<Menu> menus = List.of(
Menu.builder().id(1).menuName("System Management").build(),
Menu.builder().id(2).menuName("User Management").parentId(1).build(),
Menu.builder().id(3).menuName("Role Management").parentId(1).build(),
Menu.builder().id(4).menuName("Statistics Report").build(),
Menu.builder().id(5).menuName("Statistics by Month").parentId(4).build()
);
menuRepository.saveAll(menus);Entity
| |
Repository
| |
Queries Problem
| |
output
Hibernate: select m1_0.id,m1_0.menu_name,m1_0.parent_id from menu m1_0 where m1_0.parent_id is null
Parent Id is null - Menu count = 2
Hibernate: select cl1_0.parent_id,cl1_0.id,cl1_0.menu_name from menu cl1_0 where cl1_0.parent_id=?
Menu name = System Management - sub menu count = 2
Hibernate: select cl1_0.parent_id,cl1_0.id,cl1_0.menu_name from menu cl1_0 where cl1_0.parent_id=?
Menu name = Statistics Report - sub menu count = 1Entity
| |
Repository
| |
Solution-1
| |
output
Hibernate: select m1_0.id,cl1_0.parent_id,cl1_0.id,cl1_0.menu_name,m1_0.menu_name,m1_0.parent_id from menu m1_0 left join menu cl1_0 on m1_0.id=cl1_0.parent_id where m1_0.parent_id is null
Parent Id is null - Menu count = 2
Menu name = System Management - sub menu count = 2
Menu name = Statistics Report - sub menu count = 1JOIN FETCH
data.sql
insert into posts (id, title, content, author)
values (1, 'Post Title 1', 'Post content 1', 'Mr. J');
insert into posts (id, title, content, author)
values (2, 'Post Title 2', 'Post content 2', 'Mr. J');
insert into posts (id, title, content, author)
values (3, 'Post Title 3', 'Post content 3', 'Mr. J');
insert into posts (id, title, content, author)
values (4, 'Post Title 4', 'Post content 4', 'Mr. J');
insert into posts (id, title, content, author)
values (5, 'Post Title 5', 'Post content 5', 'Mr. J');
insert into comments (id, content, author, post_id)
values (1, 'Comment on Post-1 ', 'Mr. J', 1);
insert into comments (id, content, author, post_id)
values (2, 'Comment on Post-1 ', 'Mr. J', 1);
insert into comments (id, content, author, post_id)
values (3, 'Comment on Post-2 ', 'Mr. J', 2);
insert into comments (id, content, author, post_id)
values (4, 'Comment on Post-3 ', 'Mr. J', 3);
insert into comments (id, content, author, post_id)
values (5, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (6, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (7, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (8, 'Comment on Post-5 ', 'Mr. J', 5);Entity
| |
Entity
| |
Repository
| |
Queries Problem
| |
output
Hibernate: select c1_0.id,c1_0.author,c1_0.content,c1_0.post_id from comments c1_0
... Comment count = 8
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-1 ] from Post [Post Title 1]
... Comment [Comment on Post-1 ] from Post [Post Title 1]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
2024-03-27T12:26:15.217+08:00 ... Comment [Comment on Post-2 ] from Post [Post Title 2]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-3 ] from Post [Post Title 3]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-4 ] from Post [Post Title 4]
... Comment [Comment on Post-4 ] from Post [Post Title 4]
... Comment [Comment on Post-4 ] from Post [Post Title 4]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-5 ] from Post [Post Title 5]Solution-1
| |
output
Hibernate: select c1_0.id,c1_0.author,c1_0.content,p1_0.id,p1_0.author,p1_0.content,p1_0.title from comments c1_0 join posts p1_0 on p1_0.id=c1_0.post_id
...Comment count = 8
...Comment [Comment on Post-1 ] from Post [Post Title 1]
...Comment [Comment on Post-1 ] from Post [Post Title 1]
...Comment [Comment on Post-2 ] from Post [Post Title 2]
...Comment [Comment on Post-3 ] from Post [Post Title 3]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-5 ] from Post [Post Title 5]