jpa 공부를 하던 중 의문이 생긴 지점이 있다.
먼저, 코드를 보면 Member 엔티티를 다음과 같이 생성하여 db 에 저장한 후 다시 찾아오려고 하였다.
문제 상황
Member member = new Member();
member.setUserName("AAA");
em.persist(member); // 영속화
em.flush(); // db 반영
em.clear(); // 영속성 컨텍스트 초기화
Member findMember = em.find(Member.class, member.getId()); // Member 찾기
의문점
위 코드를 보면 flush 하여 db 에 Member 엔티티를 저장해준 후 clear 하여 영속성 컨텍스트를 초기화시켰다. 영속성 컨텍스트를 초기화했다면 1차 캐시에 있던 Member 엔티티 정보가 없어진다.
그런데 여기서!! clear 후 식별자로 find 하기 위해 member.getId() 를 호출하였을 때 어떻게 id를 가져올 수 있는지 의문이었다. 영속성 컨텍스트는 비워져 있으니까 id를 알아오기 위해선 db에 접근을 해야 하지 않을까?
그래서 getId() 호출 시 혹시나 db에 자동으로 쿼리가 나가는지 확인해 보았다.
=============MEMBER ID ===============
member id = 1
=============MEMBER FIND===============
Hibernate:
select
m1_0.MEMBER_ID,
m1_0.city,
m1_0.street,
m1_0.zipcode,
m1_0.USERNAME,
m1_0.endDate,
m1_0.startDate
from
Member m1_0
where
m1_0.MEMBER_ID=?
위는 member.getId() 만 해주었을 때, 밑에는 em.find() 를 호출하였을 때이다. getId() 시에 쿼리가 나가지 않고 그대로 1값이 출력되기만 하는 것을 확인할 수 있었다. 그렇다면 자동 쿼리가 나가지 않는다는 것은 확인되었다. 그러면 Member 객체에 id 값이 이미 세팅이 되어 있다는 것인데 언제 세팅이 되는 것일까.
그래서 em.persist 전후로 getId() 호출하여 결과를 프린트해보았다.
(참고: 현재 Member 의 id 값은 @GeneratedValue 를 사용하여 db 로부터 id를 자동 생성하도록 하였다.)
member id = null
=============PERSIST BEFORE==============
Hibernate:
select
next value for Member_SEQ
=============PERSIST AFTER==============
member id = 1
persist 전에 id 값을 찍어보면 당연히 id를 직접 설정해주지 않았으므로 null 값이 나온다.
그 다음, persist 하여 영속화했을 때 next value for Member_SEQ 가 찍히는 것을 볼 수 있는데 이것은 영속성 컨텍스트에 엔티티를 영속화하기 위해 id, 즉 pk 값이 될 시퀀스 순번을 받아온 것이다.
그 다음, persist 후의 getId() 결과를 출력한 이때!!!! persist 만 해주었는데 getId() 결과가 1로 찍히는 것을 볼 수 있다. 따라서, persist 시에 Member 객체의 id 값이 세팅된 것이다.
결론
=> 위의 결과대로 찾아본 결과, em.persist() 시에 영속화를 위해 id 값을 가져오면서 동시에 Member 객체에 가져온 id 값을 세팅해준다는 것을 알게 되었다. 따라서, em.find 부분에서 member.getId() 으로 id 값을 바로 가져와 사용할 수 있었던 것이다.
'JPA' 카테고리의 다른 글
| [JPA] JPA 사용을 위한 설정과 동작 이해 (0) | 2024.02.01 |
|---|---|
| [JPA] JPA란 무엇인가? (1) | 2024.01.31 |
| [JPA] JPA의 등장 배경은? (0) | 2024.01.31 |