Reference. 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online
이전 글
더보기
1. EntityManager
- 실질적인 쿼리를 실행하는 역할 (
persist()
,merge()
,remove()
등)
- Spring Data JPA는
EntityManager
를 래핑해서 쉽게 사용- 내부적인 실제동작은
EntityManager
를 통해 실행
- 내부적인 실제동작은
- 기능 추가, 성능 이슈 등 커스텀이 필요한 경우 EntityManager를 직접 받아 처리
Hibernate
에서 제공하는SessionImpl
구현체 사용(HibernateEntityManagerImplements
)
Hibernate
에서EntityManager
를Session
이라고 사용
2. EntityManager cache (1차 캐쉬)
- 1차캐쉬는 Map의 형태 (key: id, value: Entity)
- 실행순서
- 1차 캐쉬 조회
2-1. 값이 있는 경우 리턴
2-2. 값이 없는 경우 DB 조회 후 1차 캐쉬 저장 후 리턴
- 1차 캐쉬 조회
Id값
을 통해 1차 캐쉬를 사용할 수 있음 (다른 컬럼 조회에선 캐쉬는 캐쉬적용이 안됌)Id값을 이용한 1차 캐쉬
@SpringBootTest @Transactional //실행로직을 하나의 Transaction으로 묶기 위함 public class EntityManagerTest { @Test void cacheFindTest(){ System.out.println(userRepository.findById(1L).get()); System.out.println(userRepository.findById(1L).get()); } }
//결과 //DB에는 1번만 조회 후 캐쉬에서 값을 조회 Hibernate: select user0_.id as id1_7_0_, user0_.created_at as created_2_7_0_, user0_.updated_at as updated_3_7_0_, user0_.email as email4_7_0_, user0_.gender as gender5_7_0_, user0_.name as name6_7_0_, userhistor1_.user_id as user_id6_8_1_, userhistor1_.id as id1_8_1_, userhistor1_.id as id1_8_2_, userhistor1_.created_at as created_2_8_2_, userhistor1_.updated_at as updated_3_8_2_, userhistor1_.email as email4_8_2_, userhistor1_.name as name5_8_2_, userhistor1_.user_id as user_id6_8_2_ from user user0_ left outer join user_history userhistor1_ on user0_.id=userhistor1_.user_id where user0_.id=? User(super=BaseEntity(createdAt=2021-08-07T09:09:06, updatedAt=2021-08-07T09:09:06), id=1, name=martin, email=martin@fastcampus.com, gender=null) User(super=BaseEntity(createdAt=2021-08-07T09:09:06, updatedAt=2021-08-07T09:09:06), id=1, name=martin, email=martin@fastcampus.com, gender=null)
Id값이 아닌 컬럼의 조회 (1차 캐시 적용 X)
@Test void cacheFindTest(){ System.out.println(userRepository.findByEmail("martin@fastcampus.com")); System.out.println(userRepository.findByEmail("martin@fastcampus.com")); }
Hibernate: select user0_.id as id1_7_, user0_.created_at as created_2_7_, user0_.updated_at as updated_3_7_, user0_.email as email4_7_, user0_.gender as gender5_7_, user0_.name as name6_7_ from user user0_ where user0_.email=? User(super=BaseEntity(createdAt=2021-08-07T09:23:55, updatedAt=2021-08-07T09:23:55), id=1, name=martin, email=martin@fastcampus.com, gender=null) Hibernate: select user0_.id as id1_7_, user0_.created_at as created_2_7_, user0_.updated_at as updated_3_7_, user0_.email as email4_7_, user0_.gender as gender5_7_, user0_.name as name6_7_ from user user0_ where user0_.email=? User(super=BaseEntity(createdAt=2021-08-07T09:23:55, updatedAt=2021-08-07T09:23:55), id=1, name=martin, email=martin@fastcampus.com, gender=null)
@Transactional
을 통해 쓰기 지연이 가능- 쓰기지연: 최대한 DB에 반영하는 시기를 늦춰서 반영
- 자체적으로
Entity
값을merge
하고 반영
- DB에 접근 횟수가 낮아져 성능향상이 가능 (반영할 쿼리 모으고 한번에 적용)
- 자체적으로
save()
,delete()
,update()
를 실행하는 시점에 DB반영하지 않음
- 실행로직들이
Transaction
으로 묶여있지 않다면 그때마다 반영save()
등의 메소드는 자체@Transactional
로 묶여있음
- 메소드, 클래스에
@Transactional
로 선언하지 않으면 각자 메소드가 독립적 실행
@Transactional @Override public <S extends T> S save(S entity) { ...
- 쓰기지연: 최대한 DB에 반영하는 시기를 늦춰서 반영
- 영속성 컨텍스트에 데이터를 DB반영하는 방법 (동기화 시점)
flush()
를 사용 (개발자의 의도적 사용)- 남발하면 영속성 컨텍스트에 장점을 모두 잃음
Transaction commit
이 발생하는 경우AutoFlush
가 발생
- Test에선 마지막에
commit
하지 않고rollback
하기 때문에 로직 실행X
JPQL
이 실행될 경우AutoFlush
가 발생
select * from user
를 통해 조회 쿼리를 실행
- 영속성 컨텍스트에만 수정데이터가 반영되있기 때문에 DB와 값이 다른 현상 발생
AutoFlush
를 통해 값을 동기화시키고 반영된 값까지 조회
@Test void cacheFindTest2() { User user = userRepository.findById(1L).get(); user.setName("marrrrrrrrrtin"); userRepository.save(user); System.out.println("-------------------------------------------------"); user.setEmail("martin@gmail.com"); userRepository.save(user); System.out.println(userRepository.findAll()); }
... ------------------------------------------------- --flush()가 없지만 update가 실행 됌 Hibernate: update user set updated_at=?, email=?, gender=?, name=? where id=? ...
'백엔드 > JPA' 카테고리의 다른 글
[ JPA ] 6-4. 트랜잭션 매니저 (TransactionManager) (0) | 2021.08.08 |
---|---|
[ JPA ] 6-3. Entity 생명주기 (1) | 2021.08.08 |
[ JPA ] 6-1. 영속성 컨텍스트(Persistence Context) (0) | 2021.08.07 |
[ JPA ] 5-5. Entity Relations ( N:N @ManyToMany ) (0) | 2021.08.01 |
[ JPA ] 5-4. Entity Relations ( N:1 @ManyToOne ) (0) | 2021.08.01 |