JPA는 DB에 반영이 돼야 하는 변화가 생기면 영속성 컨텍스트에 모아두고 트랜잭션이 커밋되는 시점에 한 번에 데이터베이스에 반영시킨다.
이것을 쓰기 지연 전략이라고 한다.
분명 나는 개념을 이렇게 알고 있었고, 문제는 아래의 테스트에서 발견됐다.
@BeforeEach
void setUp(){
User user = User.builder()
.email("test@test.com")
.profileImage("ex")
.nickname("ex")
.isOnline(false)
.type("kakao").build();
User save = userRepository.save(user);
System.out.println(save.getId());
}
User 객체를 하나 생성하고 save를 진행한다.
그러면 원래 알고 있던 개념으로는 아직 insert 쿼리가 나가지 않은 상태이기에 출력은 null이 나와야 정상이다.
아니 근데 왜 insert 쿼리도 바로 나가고 pk값도 제대로 출력이 나오지???
분명 내가 아는 개념으로는 insert쿼리가 바로 나가면 안되는데 save를 하자마자 쿼리가 날라간다.
해답은 pk 전략에서 찾을 수 있었다.
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
현재 User 클래스의 id는 IDENTITY로 둬서 DB의 전략을 따르도록 만들어놨다.
즉 PK 생성을 AUTO_INCREMENT로 뒀다.(MySQL 기준)
Entity가 영속 상태가 되려면 식별자가 꼭 필요하다.
그래서 해당 식별자를 알아내기 위해 save를 하는 순간 insert 쿼리가 DB에 전달되는 것이다.
결국 해당 전략에서는 JPA의 쓰기 지연 전략이 사용되지 않는다는 중요한 점을 파악할 수 있었다.
그런데 여태 프로젝트를 진행하면서 Entity의 pk가 IDENTITY가 아닌 적이 없었다.
그 말은 여태 save를 하면 바로 insert 쿼리가 날라갔다는 의미이다.
반응형
'기타' 카테고리의 다른 글
GenerationType.IDENTITY는 정말로 쓰기 지연이 안 먹힐까? (0) | 2024.03.25 |
---|---|
어떻게 HTTP는 로그인된 상태를 판단할까? (0) | 2024.02.07 |
FETCH JOIN 사용하면서 깨달은 1차 캐시 (0) | 2024.01.18 |
인텔리제이에서 Lombok을 사용해보자.(IntelliJ) (0) | 2023.06.14 |