인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

조태준님의 프로필 이미지

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

프록시

getReference 하고 find

작성

·

39

0

getReference() 를 먼저 하고 find() 를 하면 두 경우 다 프록시 객체를 반환하는 것을 확인하였습니다.

근데 find() 를 할 때 초기화 작업이 이루어지더라고요.

저는 이때도 초기화 작업이 안 일어나고, 후에 해당 프록시 객체의 값을 사용할 때 초기화 작업이 일어날 줄 알았습니다.

 

이것을 그럼 아래와 같이 이해를 하면 될까요?

  • find() 는 어쨋든 진짜 객체를 가져오는 메서드이므로 DB에 간다(초기화 작업이 일어난다)

  • 하지만 getReference() 로 인해 이미 프록시 객체가 영속성 컨텍스트에 있고

  • 같은 트랜잭션에서 영속성 컨텍스트의 동일성을 보장하기 위해 프록시 객체를 반환한다

답변 3

0

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

안녕하세요. 조태준님

네 생각하신 내용이 맞습니다 🙂

JPA는 영속성 컨텍스트의 동일성( == 비교)를 보장합니다.

따라서 같은 식별자로 조회시 객체가 다르면 안됩니다. 이런 문제를 해결하기 위해 최초에 프록시로 조회하면 계속 같은 프록시 객체가 조회되고, 최초에 진짜 엔티티를 조회하면 진짜 엔티티가 계속 조회됩니다.

물론 최초에 프록시로 조회했는데, 한번 초기화가 되었다면 이후에 조회한 프록시 객체도 초기화 된 상태로 조회됩니다.

감사합니다.

0

조태준님의 프로필 이미지
조태준
질문자

제가 이해한 게 맞나요?

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 조태준님.

질문해주신 내용은 JPA에서의 프록시와 영속성 컨텍스트의 동작 방식에 대한 이해를 필요로 합니다. JPA에서 getReference()find() 메서드의 특성과 이들이 프록시 객체와 실제 엔티티 객체를 처리하는 방법은 다음과 같습니다:

  1. getReference(): 이 메서드는 즉시 DB 조회를 수행하지 않고 엔티티의 프록시 객체를 반환합니다. 이 프록시 객체는 실제 데이터가 필요할 때까지 데이터베이스 조회를 연기합니다.

  2. find(): 이는 실제 엔티티 객체를 반환하며, 필요하다면 DB 조회가 수행됩니다. 하지만 영속성 컨텍스트는 동일성(identity)을 보장하기 때문에 해당 엔티티에 대한 프록시가 이미 존재한다면 그 프록시 객체를 반환합니다.

  3. 초기화 작업: find() 메서드를 호출했을 때 프록시 객체가 이미 존재하면, 그 객체가 반환되며, 이 때 내부적으로 초기화 작업이 수행될 수 있습니다. find() 자체는 기본적으로 실제 엔티티 데이터를 조회하기 위한 메서드이지만, 영속성 컨텍스트의 동일성 보장 때문에 프록시 객체가 반환될 때 이미 초기화가 일어날 수 있습니다.

질문하신 내용을 요약하면, find()를 사용했을 때 영속성 컨텍스트에 프록시가 이미 있다면, 그 프록시 객체를 사용하게 되지만, find()의 특성상 데이터베이스에서 실제 데이터를 가져오기 위한 처리를 수행할 수 있으며 이로 인해 초기화가 이루어질 수 있다는 것입니다.

더 구체적인 이해를 돕기 위해 다음의 유사한 질문과 답변을 확인해보세요:

  • JPA: 사전에 프록시 객체가 조회되고, find() 호출 시 초기화와 관련된 지식을 공유해 주신 김영한 강사님의 답변입니다.

위 설명이 조태준님의 이해에 도움이 되었길 바랍니다. 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.