Skip to content

Latest commit

 

History

History
70 lines (57 loc) · 5.31 KB

08.프록시와연관관계정리.md

File metadata and controls

70 lines (57 loc) · 5.31 KB

06. 프록시와연관관계정리

✔️ 8.1. 프록시 기초

  • EntityManager.getReference()는 디비 접근을 위임한 프록시 객체를 반환함
  • 프록시 클래스는 실제 클래스를 상속 받아서 만들어지므로 실제 클래스와 겉 모양이 같다. 사용자 입장에서는 이것이 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다.
  • 프록시 객체는 실제 객체에 대한 참조를 보관한다. 프록시 객체의 메소드를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.
  • 프록시 객체는 getName()처럼 실제 사용될 때 데이터베이스를ㄹ 조회해서 실제 엔티티 객체를 생성하는데 이것을 프록시 객체의 초기화라고 한다.
  • 프록시 특징
      1. 프록시 객체는 처음 사용할 때 한 번만 초기화된다.
      1. 프록시 객체를 초기화한다고 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 프록시 객체가 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근할 수 있다.
      1. 프록시 객체는 원본 엔티티를 상속받은 객체이므로 타입 체크시에 주의해서 사용해야한다.
      1. 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 데이터베이슬를 조회할 필요가 없으므로 getReference가 실제 엔티티를 반환한다.
      1. 준영속 상태에서는 초기화할 수 없다.(당연...)

✔️ 8.1.2 프록시와 식별자

  • 엔티티는 프록시로 조회할 때 PK 값을 파라미터로 전달하는데 프록시 객체는 이 식별자 값을 보관한다.
  • 프록시 객체는 식별자 값을 가지고 있으므로 식별자 값을 조회하는 team.getId()를 호출해도 프록시를 초기화하지 않는다. 단 엔티티 접근 방식을 프로퍼티로 설정한 경우에만 초기화되지 않는다.
  • 엔티티 접근방식을 필드로 설정했을 경우 해당 메서드가 id만 사용하는 것은지 다른 필드까지 활용해서 어떤 일을 하는 메서드 인지 판달할 수 없으므로 프록시객체를 초기화한다.
  • 연관관계 설정시에는 필드로 접근방식 설정해도 초기화 x

✔️ 8.2.1 즉시로딩

  • 연관관계 엔티티를 바로 로딩하는 것
  • 대부분의 JPA 구현체는 즉시 로딩을 최적화하기 위해 가능하면 조인 쿼리를 사용한다.

✔️ 8.2.2 지연로딩

  • 데이터가 필요한 순간 로딩

✔️ 8.2.3 정리

  • 지연로딩 : 연관된 엔티티를 프록시로 조회한다. 실제 사용할 때 초기화하면서 디비 조회
  • 즉시로딩 : SQL 조인을 사용해서 한 번에 조회한다. Nullable예따라 inner, outer 조인 결정됨.

✔️ 8.3.1 프록시와 컬렉션 래퍼

  • 지연로딩으로 설정하면 실제 엔티팉 대신에 프록시 객체를 사용한다.
  • 하이버네이트는 엔티티를 영속 상태롤 만들때 엔티티에 컬렌션이 있으면 컬렉션을 추적하고 관리할 목적으로 원본 컬렉션을 하이버네이트가 제공하는 내장 컬렉션을 변경하는데 이를 컬렉션 래퍼라 한다.
  • 컬렉션은 컬렉션래퍼가 지연로딩을 처리해준다. 따라서 구분없이 프록시로 간주해도 됨.

✔️ 8.3.2 JPA 기본 패치 전략

  • JPA 기본패치 전략은 연관된 엔티티가 하나면 즉시 로딩을, 컬렉션이면 지연로딩을 사용한다.
  • 컬렉션을 로딩하는 것은 비용이 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문
  • 추천한느 방법은 모든 연관관계에 지연로딩을 사용하는 것.

✔️ 8.3.3 컬렉션에 즉시로딩 사용시 주의 점.

  • 컬렉션을 하나 이상 즉시 로딩하는 것은 권장하지 않는다.
  • 컬렉션과 조인한다는 것은 디비 테이블로 보면 일대다 조인이다. 일대다 조인은 결과 데이터가 다 쪽에 있는 수만큼 증가하게 된다. M*N
  • 컬렉션 즉시로딩은 항상 outer 조인 사용한다. 없을때의 경우에 대비

✔️ 8.4 영속성 전이

  • 특정 엔티티를 영속 상태롤 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이를 사용한다.
  • JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야한다. 따라서 부모/자식 모든 각각 영속상태로 만들어 줘야한다.
  • CASCADE = type.PERSIST 저장시 자식도 같이 영속화
  • CASCADE = type.REMOVE 삭제시 자식도 같이 영속화
  • CASCADE = type.MERGE 병합시 자식도 같이 영속화
  • CASCADE = type.RRFESH
  • CASCADE = type.DETACH
  • CASCADE = type.ALL

✔️ 8.5 고아객체

  • 부모 엔티티와 연관관계가 끊어진 자식엔티티
  • 부모엔티티 컬렉션에서 자식 엔티티의 참조만 제거하면 자식엔티티가 자동으로 삭제되도록 할 수 있음.
  • orphanRemoval = true
  • @oneToMany, @manyToOne에만 사용가능함.

✔️ 결론

  • JPA 구현체들은 객체 그래프를 맘껏 탐색할 수 있는데, 이때 프록시 기술을 사용한다.
  • 즉시로딩/지연로딩
  • 영속성 전이 : 객체 저장 또는 삭제시 연관된 객체도 함께 저장/삭제하는 것
  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하려면 고아 객체 제거 기능을 사용한다.