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

Updated:

김영한님의 인프런 강의 - 자바 ORM 표준 JPA 프로그래밍 - 기본편
위 강의를 정리한 내용입니다.

I. 프록시

프록시?

  • em.find() : 데이터베이스를 통해서 실제 엔티티 객체 조회
  • em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
  • 프록시 특징
    • 실제 클래스를 상속 받아서 만들어짐
    • 실제 클래스와 겉 모양이 같음
    • 프록시 객체는 처음 사용할 때 한 번만 초기화
    • 초기화 할 때, 실제 엔티티로 바뀌는 것은 아님. 프록시 객체를 통해 실제 엔티티에 ‘접근 가능’해진다.
    • 프록시 객체는 원본 엔티티를 상속받는 것이기 때문에 ==비교 시 실패.
    • 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해도 실제 엔티티 반환
      • 이미 1차캐시에 있는데 굳이 한번 거쳐서 가져올 필요가 없다.
    • 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 떄, 프록시를 초기화하면 문제 발생

(궁금점) Q. em.getReference()를 통해 프록시 객체를 선언하는 순간에는 아직 영속성 컨텍스트에는 찾으려 하는 엔티티가 올라오지 않았다. 그러나 em.clear()로 영속성 컨텍스트를 비우면 기존 프록시 객체를 초기화 하려 할 때 오류가 난다. 어째서?????

A. 프록시 객체를 선언하는 순간 프록시 객체도 영속성 컨텍스트에 올라가게 된다. 따라서 영속성 컨텍스트를 초기화하거나 닫거나, 또는 프록시 객체를 detach하게 되면 프록시 객체를 정상적으로 초기화할 수 없게 된다.

II. 즉시 로딩과 지연 로딩

  • Member와 Team을 항상 함께 조회할 필요가 없다면?
    • 지연로딩 LAZY 사용하면 프록시로 조회
  • Member와 Team을 같이 조회하는 일이 많다면?
    • 즉시로딩 EAGER를 사용하면 함께 조회

프록시와 즉시로딩 주의

  • 가급적 지연 로딩만 사용(특히 실무에서)
  • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
  • @ManyToOne, OneToOne은 즉시로딩이 기본설정 -> LAZY로 바꿔주기

III. 영속성 전이(CASCADE)와 고아 객체

영속성 전이(CASCADE)

  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속상태로 만들고 싶을 때
  • 연관관계를 매핑하는 것과는 관련X
  • 연관 엔티티를 함께 영속화하는 편리함을 위해 사용
  • cascade = CascadeType.XXX
    • ALL : 모두 적용
    • PERSIST : 영속화
    • 위 두개만 사용해도 충분
  • 언제 사용?
    • 두 엔티티의 라이프사이클이 같을 때
    • 개인 소유 관계일 때

고아 객체

  • 고아 객체 제거 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
  • orphanRemoval = true
  • 참조하는 곳이 하나일 때 사용 : 특정 엔티티가 개인 소유 할 때

영속성 전이와 고아 객체를 함께 사용하는 의미

  • 자식 엔티티의 생명 주기를 부모 엔티티가 모두 관리할 수 있음

Leave a comment