섹션 3 지연 로딩 설정 후 MemberTest 실행 후 쿼리 문
이전 강의를 수강 하면서 엔티티 조회 시 지연 로딩 설정 시 즉시 조회가 되는 게 아닌 프록시 객체가 데이터의 위치를 가지고 사용할 때에 프록시 객체가 초기화 되며 데이터베이스에 쿼리를 요청하고 데이터를 받아 온다 라고 배웠습니다. 그렇다면 테스트 메서드를 실행하게 된다면Team, Member 객체를 persist -> 영속성 컨텍스트에 Member와 Team 존재flush() -> 영속성 컨텍스트에 들어있던 엔티티를 데이터베이스에 반영 -> insert 쿼리가 실행데이터베이스에 반영되었으나 아직 영속성 컨텍스트에는 값이 존재하는 상태clear() -> 영속성 컨텍스트에 들어 있는 데이터를 초기화createQuery로 Member 엔티티를 데이터베이스에서 조회 -> Member에 대한 select 쿼리 실행영속성 컨텍스트가 초기화 되었고 team이 지연 로딩으로 설정되어 프록시 객체가 생성루프를 돌며 getTeam() 호출 시점 team_id를 기반으로 데이터베이스에 team을 조회 -> Team에 대한 select 쿼리 실행memberA 조회 후 teamA에 대한 조회 쿼리가 발생하고 memberC 조회 후 teamB 조회 쿼리가 발생이러한 과정으로 이뤄진다고 배웠는데 테스트 코드를 돌려보니 member에 대한 조회 쿼리 후 team에 대한 조회 쿼리가 발생하지 않습니다.그래서 팀의 프록시 객체가 초기화 되었는지 체크하기 위해 Hibernate.isInitialized를 사용해 찍어봤는데 제일 처음 false 로 초기화 되지 않았다고 나오나 team을 조회하는 쿼리가 발생하지 않았습니다.찾다 보니 Hibernate에 쿼리 최적화 기능으로 영속성 컨텍스트는 초기화 되었지만 메모리가 초기화 된 것은 아니므로 해당 객체가 메모리에 존재한다면 Hibernate가 쿼리를 생략하고 해당 객체를 반환한다라는 게 있던데 그것 때문에 쿼리가 나가지 않는 건지 궁금합니다. 2차 캐시가 설정되어 있지는 않습니다. 스프링 부트 3.3.4, 자바 17, Hiberante 6.5.3 입니다!* 해결 *spring.jpa.properties.hibernate.show_sql=true하이버네이트 show_sql이 주석처리 format_sql만 출력되는 상황이었습니다.정상 출력 확인했습니다!package springPJ.dataJpa.domain;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Hibernate;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@RequiredArgsConstructor
@Slf4j
class MemberTest {
@Autowired
EntityManager em;
@Test
void testEntity() {
Team teamA = Team.builder().name("teamA").build();
Team teamB = Team.builder().name("teamB").build();
em.persist(teamA);
em.persist(teamB);
Member memberA = Member.builder().name("memberA").age(10).team(teamA).build();
Member memberB = Member.builder().name("memberB").age(20).team(teamA).build();
Member memberC = Member.builder().name("memberC").age(30).team(teamB).build();
Member memberD = Member.builder().name("memberD").age(40).team(teamB).build();
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
em.persist(memberD);
em.flush();
em.clear();
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
for (Member member : members) {
log.info("team.isInitialized = {}", Hibernate.isInitialized(member.getTeam()));
log.info("member = {}", member);
log.info("member.team = {}", member.getTeam());
}
}
} select
m1_0.member_id,
m1_0.age,
m1_0.name,
m1_0.team_id
from
member m1_0
2024-09-21T19:36:05.194+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : team.isInitialized = false
2024-09-21T19:36:05.194+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member = Member(id=1, name=memberA, age=10)
2024-09-21T19:36:05.197+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member.team = Team(id=1, name=teamA)
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : team.isInitialized = true
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member = Member(id=2, name=memberB, age=20)
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member.team = Team(id=1, name=teamA)
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : team.isInitialized = false
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member = Member(id=3, name=memberC, age=30)
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member.team = Team(id=2, name=teamB)
2024-09-21T19:36:05.219+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : team.isInitialized = true
2024-09-21T19:36:05.220+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member = Member(id=4, name=memberD, age=40)
2024-09-21T19:36:05.220+09:00 INFO 7696 --- [dataJpa] [ Test worker] springPJ.dataJpa.domain.MemberTest : member.team = Team(id=2, name=teamB)