자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (8-2) 프록시와 연관관계 관리
들어가며
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) : 외부 조인
- @ManyToOne, @OneToOne
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에만 사용 가능
'Book' 카테고리의 다른 글
자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (10-1) 객체 지향 쿼리 언어 (0) | 2022.10.05 |
---|---|
자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (9) 값 타입 (0) | 2022.09.18 |
자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (8-1) 프록시와 연관관계 정리 (0) | 2022.08.27 |
자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (7-2) 고급매핑 (0) | 2022.08.24 |
자바 ORM 표준 JPA 프로그래밍 - JPA 정리하기 (7-1) 고급매핑 (0) | 2022.08.17 |
댓글