해결된 질문
작성
·
386
4
안녕하세요 영한님! 강의 내용 중 궁금한 점이 있어 질문 드립니다.
Team refTeam = em.getReference(Team.class, 1L);
refTeam.getName();
을 하게되면 Proxy가 비어있으므로
1. 영속성 컨텍스트에 초기화 요청을 보내고,
2. 영속성 컨텍스트가 DB를 조회해
3. 실제 엔티티 객체를 생성
은 이해가 되었습니다.
그럼 여기서 영속성 컨텍스트가 실제 엔티티 객체를 생성하고 Proxy의 target에 연결을 해줄 뿐이지, 1차 캐시에 실제 엔티티가 저장되는 것은 아닌 건가요? 1차 캐시에는 'Proxy 객체만' 있고 Proxy의 target을 통해 실제 엔티티를 접근할 수 있는 건지 궁금하여 질문 드립니다!
감사합니다.
답변 2
4
0
답변 감사드립니다! 제가 잘못 이해하고 있던 부분인 것 같습니다.
Entity entity = getReference(...)
-> 영속성 컨텍스트에 Proxy 저장
-> entity에 Proxy 반환
으로 생각하고 있었는데 getReference() 호출 시,
1. 영속성 컨텍스트에서 값이 있는지 확인 (있다면 그것을 반환)
2. 없다면 Proxy 객체를 반환 (이 때 영속성 컨텍스트에는 아무것도 저장되지 않음)
3. entity.getName()으로 Proxy 초기화 시, 이때 DB를 조회해 생긴 '실제 엔티티가 1차 캐시에 저장'되고, 실제 엔티티를 Proxy의 target이 참조
라고 이해하면 될까요?
만약 그렇다면... 조금 주제를 벗어난 질문이지만,
Q. 동일한 영속성 컨텍스트에서, '다시 동일한 데이터를 find() 해도 Proxy를 반환해준다' 하셨는데 JPA는 어떻게 Proxy를 먼저 반환했던 것을 기억하고 Proxy를 반환해주는 것 인지 궁금합니다.
영속성 컨텍스트에 Proxy를 담고 있는 Map이 있습니다. Key는 Enity의 id를 사용하고요.
.
1. em.getReference(Member.class, 1L)를 하게 되면 내부에 프록시가 있는 확인합니다.
2. 프록시가 없으면 프록시를 생성하고 반환합니다. 이 과정에서 영속성 컨텍스트는 프록시를 따로 보관하는 맵에 생성된 프록시를 Key(member의 id)와 함께 담습니다.
3. 두 번째로 em.find(Member.class, 1L)를 명령하면 엔티티를 반환하기 전에 프록시를 먼저 찾습니다. em.reference() 명령 때 만들어두었던 프록시가 있기 때문에 프록시를 반환합니다.
.