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

윽이럴뚜가님의 프로필 이미지
윽이럴뚜가

작성한 질문수

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

프록시

JPA

작성

·

498

1

Member m1= em.getReference(Member.class,member1.getId());
System.out.println("m1.getClass() = " + m1.getClass());

Member m2= em.find(Member.class,member1.getId());
System.out.println("m2.getClass() = " + m2.getClass());
System.out.println("m1==m2"+(m1.getClass() == m2.getClass()));

System.out.println(" =============== ");

1. 제가 예상한것은 영속성 컨텍스트에 프록시 객체가 담길것이고,

2. find 해서 가져오려 했으나 영속성 컨텍스트에 Member객체가 있기에 db로 안가고

    프록시 객체를 그냥 가져와서 true가 나온다...

가 예상이었슴다.

근데 결과는 2번이 약간 달랐죠

일단 db로 쿼리는 select 때린다.

근데 가져온것은 프록시 객체.  ㅡㅡ.... 아니 DB왜 간거지...

DB까지 간것이 맞고 그 내용까지 JPA 자기 눈으로 직접 보았으나 일단 영속성 컨텍스트에 이미 있으니 DB에서 가지고 온것을 '버리자!!!' 하고 그냥 앞의 프록시 객체를 사용을 하는건가요?

제가 이해한게 맞나여? 강사님

답변 1

4

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

안녕하세요. 윽이럴뚜가님^^

em.getReference는 프록시를 조회하는 것이고, em. find는 실제 데이터가 존재하는 엔티티를 찾은 기능입니다.

JPA는 같은 트랜잭션에서 영속성 컨텍스트의 동일성을 보장하기 때문에 PK가 같으면 항상 같은 인스턴스를 반환합니다. em.getReference나 em.find 둘다 같은 PK이면 같은 객체 인스턴스가 조회되어야 합니다.

그래서 둘다 같은 인스턴스가 조회된 것은 맞습니다.

그런데 여기서 em.find() 같은 경우에는 실제 데이터가 존재하는 객체를 조회해야 하는데 이미 프록시 객체로 조회가 되어버린 상황입니다. 따라서 영속성 컨텍스트의 동일성을 보장하기 위해 해당 프록시 객체를 그대로 반환하되, 내부에서 프록시를 한번 초기화 해준다고 이해하시면 됩니다.

감사합니다.^^

윽이럴뚜가님의 프로필 이미지
윽이럴뚜가

작성한 질문수

질문하기