• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

자바 ORM 표준 JPA 프로그래밍 기본 - 8.프록시와 연관관계 관리

23.08.30 22:08 작성 23.08.30 22:11 수정 조회수 273

0


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

[질문 내용]
8.프록시와 연관관계 관리 강의 중에서 프록시 부분 설명하실때 이해가 안되는 부분이 있는데요

  1. em.getReference()하면 프록시 객체가 영속성 컨테스트에 생성되는 건가요??

  2. JpaMain 클래스에서 코드 작성하실때

    Member member1 = new Member();

    member1.setUsername("member1");

    em.persist(member1);

    em.flush();

    em.clear();

    Member refMember = em.getReference(~,member1.getId());

    refMember.getUsername();

이렇게 작성하셨는데 아래쪽에 프록시 객체 생성하고 refMember.getUsername()할때 왜 db에 select문이 나가는 건가요??영속성 컨텍스트에 없어서 그런건가요???

  1. 그리고 위의 코드에서 refMember.getUsername(); 할때 프록시를 초기화 한다고 하셨는데 getter 메서드쓰는게 어떻게 초기화를 하는건가요??프록시에 getUsername()을 하면 프록시에 username 값이 세팅되는 건가요?? 프록시는 target 이랑 진짜 객체의 메소드만 갖고있는거 아닌가요???

답변 1

답변을 작성해보세요.

2

안녕하세요. 황지호님

1. em.getReference()하면 프록시 객체가 영속성 컨테스트에 생성되는 건가요??

- 네, 맞습니다. em.getReference()를 호출하면, 해당 엔티티의 실제 인스턴스가 아닌 프록시 객체가 생성되어 영속성 컨텍스트에 반환됩니다. 이 프록시 객체는 실제 엔티티와 동일한 인터페이스를 갖지만, 내부적으로 실제 데이터를 가지고 있지는 않습니다.

2. refMember.getUsername()할때 왜 db에 select문이 나가는 건가요??

- 영속성 컨텍스트에 엔티티가 존재하지 않기 때문입니다. 코드에서 em.flush()em.clear()를 사용하여 영속성 컨텍스트를 초기화했기 때문에 모든 엔티티가 컨텍스트에서 제거됩니다. 따라서 getReference()로 프록시 객체를 가져온 후 getUsername() 메서드를 호출하면, 실제 엔티티의 데이터가 필요한 상황이 발생합니다. 프록시 객체는 실제 데이터를 가지고 있지 않기 때문에 데이터베이스에서 해당 엔티티를 조회해야 합니다. 그 결과 SELECT 문이 실행됩니다.

3. refMember.getUsername(); 할때 프록시를 초기화 한다고 하셨는데...

- 프록시 객체는 실제 데이터를 로드하지 않는 '가벼운' 객체입니다. 그러나 실제 엔티티의 데이터에 접근하려고 할 때, 프록시 객체는 내부적으로 초기화 과정을 거칩니다. 이 초기화 과정 중에 데이터베이스로부터 실제 엔티티 데이터를 로드합니다.

- getUsername()과 같은 getter 메서드를 호출하면 프록시 객체는 이 메서드를 오버라이드하여, 데이터를 필요로 하는 경우에만 실제 엔티티 데이터를 로드하는 로직을 포함합니다. 따라서, 처음 데이터에 접근할 때 데이터베이스에 SELECT 문이 실행되어 실제 엔티티 데이터를 가져오게 됩니다.

- 프록시 객체는 실제 엔티티와 동일한 인터페이스를 가지지만, 실제 엔티티에 대한 참조(`target`)도 내부적으로 가지고 있습니다. 프록시가 초기화되면 이 target 참조는 실제 엔티티 데이터로 채워집니다.

결론적으로, 프록시 객체는 JPA에서 성능 최적화를 위해 제공하는 기능입니다. 필요한 시점에만 데이터베이스에 접근하여 실제 데이터를 로드하는 지연 로딩(Lazy Loading)의 원리를 구현하는 것이 프록시 객체의 핵심입니다.

감사합니다.