강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

도등어님의 프로필 이미지
도등어

작성한 질문수

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

JPA : 페치 조인과 준영속 상태

해결된 질문

작성

·

82

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
여기에 질문 내용을 남겨주세요.

안녕하세요! 영한님 스프링 관련 강의를 사서 항상 잘 보고 있습니다! 그리고 JPA 관련 공부는 영한님이 쓰신 JPA 책으로 공부하고 있습니다. JPA 관련 질문을 드리고 싶은데 JPA 강의는 사지 않아 질문을 올리지 못하게 되어 부득이하게 여기에 질문하게 되었습니다 죄송합니다 ㅜㅜ

 

다름이 아니라 JPA 책의 375 페이지, 10장 객체지향 쿼리 언어 파트에서 다음과 같이 페치 조인 전략 사용시 멤버가 준영속 상태가 되어도 나중에 팀을 별도의 쿼리를 날리지 않고 조회가 가능함을 확인했습니다. 책에서도 그렇게 말씀해주셨습니다!

 

그리고 그 다음에 페치 조인을 사용하지 않은 경우를 적용해보았습니다.

String query = "SELECT m FROM Member m";
Member member = em.createQuery(query, Member.class).getResultList().get(0);

em.detach(member);

System.out.println("Class Type: " + member.getTeam().getClass().getName()); // 프록시 객체임을 확인
System.out.println("Is initialized: " + Hibernate.isInitialized(member.getTeam())); // 초기화 안된 상태
System.out.println("member.getTeam() = " + member.getTeam().getName()); // 별도로 쿼리가 날아감

제 예상으로는 member.getTeam() 시 프록시 팀 객체가 형성되고, 물론 초기화는 되지 않은 상태이며 이때 멤버 객체가 준영속 상태이기 때문에 getTeam().getName()에서 예외가 발생할 것이라 생각했습니다. 왜냐하면 member - team은 lazy fetch로 되어있기 때문에 member에서 연결된 team을 조회할 때 추가적인 쿼리를 한번 더 날려야 하는데, 준영속 상태가 되면서 이것이 불가능해질 것이라 생각했기 때문입니다.

 

그런데 실제로는 추가쿼리를 날려서 값을 가져오는 것을 확인했습니다. 혹시 왜 이런 것인지 알수 있을까요?? 감사합니다. 항상 강의 잘 보고 있습니다!

답변 3

2

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 도등어님 🙂

해당 부분을 이해하려면 OSIV의 개념을 알아야 합니다.

자세한 내용은 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

강의에 있는 OSIV와 성능 최적화 부분을 참고해주세요.

감사합니다.

도등어님의 프로필 이미지
도등어
질문자

감사합니다. 해당 내용 찾아보겠습니다!

0

도등어님의 프로필 이미지
도등어
질문자

준영속 상태일 때 초기화 요청을 하면 LazyInitializationException 이 발생할 것이라 예상하였는데 그러면 하이버네이트가 준영속 객체에서 객체 그래프를 탐색할 때 초기화되지 않은 프록시 객체에 대해 자동으로 추가 쿼리를 날려 해당 데이터를 가져올 수 있게 해준다는 건가요?

0

안녕하세요, 인프런 AI 인턴입니다.

도등어님, JPA와 관련된 질문에 대해 설명드리겠습니다. JPA에서 엔티티가 준영속 상태가 되었을 때 프록시를 통한 연관 관계에 접근할 수 있는 이유는 특정 상황에서 Hibernate가 이를 허용하기 때문입니다.

준영속 상태의 엔티티는 영속성 컨텍스트로부터 분리되어 해당 엔티티에 대한 변경 사항이 자동으로 데이터베이스에 반영되지 않습니다. 하지만, 엔티티가 초기화되지 않은 프록시 객체를 통해 연관된 객체에 접근할 경우, Hibernate는 필요한 순간에 추가 쿼리를 통해 해당 데이터를 가져올 수 있습니다. 이는 Hibernate의 기본 기능으로서, 필요 시 데이터를 가져올 수 있도록 설계되어 있습니다. JPA의 기본 스펙 상에서는 이러한 동작이 보장되지 않지만, Hibernate는 이를 지원합니다.

단, 이 기능을 사용할 때는 주의가 필요합니다. 영속성 컨텍스트 외에서 엔티티에 접근하며 발생하는 성능 이슈나 데이터의 일관성 문제가 있을 수 있기 때문입니다.

영한님의 강의를 통해 공부하시는 과정에서 이러한 경험을 쌓으시면 더 깊이 있는 이해가 가능해질 것입니다. 추가로 궁금한 점이 있으면 언제든지 질문남겨주세요. 감사합니다. 강의 열심히 수강해 주세요!

출처: 질문하기 메뉴얼

도등어님의 프로필 이미지
도등어

작성한 질문수

질문하기