본문 바로가기
Book

자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (8-2) 프록시와 연관관계 관리

by devLog by Ronnie's 2022. 9. 10.

자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (8-2) 프록시와 연관관계 관리

jpa

들어가며


8강은 1편과 2편으로 나눠 진행하였다. 

 

 

8.3 지연 로딩 활용

  • 연관된 관계 끼리 자주 함께 사용 -> 즉시 로딩 설정
  • 가끔 사용 -> 지연 로딩 설정

8.3.1 프록시와 컬렉션 래퍼

  • 지연 로딩 설정 시 실제 엔티티 대신 프록시 객체를 사용하며, 프록시 객체는 실제 자신이 사용될 때까지 데이터베이스를 조회하지 않음
  • 하이버네이트는 엔티티를 영속 상태로 만들 때 엔티티에 컬렉션이 있으면 컬렉션을 추적하고 관리할 목적으로 원본 컬렉션을 하이버네이트가 제공하는 내장 컬렉션으로 변경하는데 이것을 컬렉션 래퍼라 함. (출력 결과를 보면 org.hibernate.collection.internal.PersistentBag이 반환)
  • 주문 내역과 같은 컬렉션은 컬렉션 래퍼가 지연 로딩을 처리해줌
  • member.getOrders() 와 같이 호출해도 컬렉션 초기화 x -> member.getOrders().get(0)처럼 컬렉션에서 실제 데이터 조회 시 디비 조회해서 초기화함.

8.3.2 JPA 기본 페치 전략

  • fetch 속성의 기본 설정값
    • @ManyToOne, @OneToOne : 즉시 로딩 (EAGER)
    • @OneToMany, @ManyToMany : 지연 로딩 (LAZY)
  • JPA의 기본 페치 전략은 연관된 엔티티가 하나면 즉시 로딩을 컬렉션이면 지연 로딩을 사용
  • 컬렉션을 로딩하는 것은 비용이 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문
  • 추천 방법 -> 모든 연관관계에 지연 로딩 사용 -> 개발이 어느 정도 완료 단계에서 실제 사용 상황 확인 후 꼭 필요한 곳에만 즉시 로딩을 사용하여 최적화 (이때 SQL을 직접 사용시 추후 코드 변경이 많아지므로 유연한 최적화에 어려움 있음)

8.3.3 컬렉션에 FetchType.EAGER 사용 시 주의점

  • 컬렉션을 하나 이상 즉시 로딩하는 것은 권장하지 않는다.
    • 컬렉션과 조인한다는 것은 디비 테이블로 보면 일대다 조인
    • 일대다 조인은 결과 데이터가 다 쪽에 있는 수만큼 증가
    • 문제가 되는 상황은 서로 다른 컬렉션을 2개 이상 조인하게 되면 결과가 너무 많은 데이터를 반활할 수 있게 되어 성능 저하되므로 2개 이상의 컬렉션을 즉시 로딩으로 설정하는 것은 권장 x
  • 컬렉션 즉시 로딩은 항상 외부 조인을 사용
    • 다대일 관계인 회원 테이블과 팀 테이블을 조인할 때 회원 테이블의 외래 키에 Not null 제약조건을 걸게 되면 모든 회원은 팀에 소속되므로 항상 내부조인을 사용해도 됨
    • 반대로 팀 테이블에서 회원 테이블로 일대다 관계를 조인할때 회원이 한명도 없는 팀을 내부 조인하면 팀까지 조회되지 않는 문제 발생
    • JPA는 일대다 관계를 즉시 로딩할 때 항상 외부 조인을 사용
  • FetchType.EAGER 설정과 조인 전략 정리
    • @ManyToOne, @OneToOne
      • (optional = false) : 내부 조인
      • (optional = true) : 외부 조인
    • @OneToMany, @ManyToMany
      • (optional = false) : 외부 조인
      • (optional = true) : 외부 조인

8.4 영속성 전이 : CASCADE

  • 특정 엔티티를 영속 상탤 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이 기능을 사용
  • JPA CASCADE 옵션으로 영속성 전이를 제공
  • 쉽게 말해 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장할 수 있게 해줌

8.4.1 영속성 전이: 저장

  • @OneToMany(mappedBy = “parent”, cascade = CascadeType.PERSIST) -> 설정 시 부모 영속화할 때 연관된 자식들도 함께 영속화 됨

8.4.2 영속성 전이: 삭제

  • CascadeType.REMOVE 설정 시 부모 엔티티 삭제 시 연관된 자식 엔티티로 함께 삭제됨

8.4.3 CASCADE 의 종류

  • 옵션의 종류
    • ALL
    • PERSIST
    • MERGE
    • REMOVE
    • REFRESH
    • DETACH

8.5 고아 객체

  • JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공하는데 이것을 고아 객체 제거라 함.
  • orphanRemoval = true 옵션을 통해 설정 가능 
  • 고아 객체 제거는 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
  • 만약 삭제한 엔티티를 다른 곳에서도 참조한다면 문제 발생할 수 있음
  • 이런 이유로 @OneToOne / @ OneToMany에만 사용 가능

 

 

댓글