프로그래밍공부(Programming Study)/JPA(Java Persistence API)

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

Chaany 2022. 12. 28.
728x90

1. 프록시

  • em.getReference() : 데이터베이스 조회를 미루는 가짜 엔티티 객체 조회
  • 처음 사용할 때 한 번만 초기화
  • 실제 클래스를 상속 받아서 만들어짐
  • 실제 클래스와 겉 모양이 같음
  • 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 됨
    -> == 비교 시에 true 
  • 실제 객체의 참조(target)을 보관
  • 프록시 객체 호출 시 실제 객체의 메소드 호출
  • 주의사항
    • 프록시 객체는 원본 엔티티를 상속 받기 때문에 ==비교가 아닌 instance of 사용
    • (실무에서 많이 발생)영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태(close/detach/clear)일 때, 프록시 초기화 시 문제 발생
      -> 하이버네이트는 org.hibernate.LazyInitializationException 예외를 터트림
  • 프록시 확인
    • 프록시 인스턴스의 초기화 여부 확인 PersistenceUnitUtil.isLoaded(Object entity)
    • 프록시 클래스 확인 방법 entity.getClass().getName() 출력(..javasist.. or HibernateProxy…)
    • 프록시 강제 초기화 org.hibernate.Hibernate.initialize(entity);
    • 참고: JPA 표준은 강제 초기화 없음 강제 호출: member.getName()

2. 즉시 로딩과 지연 로딩

    • 즉시로딩
      • 연관 관계 매핑된 엔티티를 함께, 자주 사용할 경우 사용
      • fetch = FetchType.EAGER / EAGER(static Import)
      • @ManyToOne, @OneToOne (XToOne)은 즉시 로딩이 default -> LAZY로 설정해주는 게 좋음
    • 지연로딩
      • 단순히 특정 엔티티 정보만 사용하는 비즈니스 로직일 경우 사용 
      • fetch = FetchType.LAZY / LAZY(static Import)
      • @OneToMany, @ManyToMany(XToMany)는 기본이 지연로딩
    • 주의사항
      • 실무에서 가급적 지연 로딩만 사용
        • 즉시 로딩 적용 시 예상하지 못한 SQL이 발생 -> 연관된 테이블이 Join되어 쿼리가 나감
        • 즉시 로딩 적용 시 JPQL에서 N+1문제 발생 
          • JPQL fetch join(대부분 사용)
          • entitygraph 어노테이션
          • batchsize(1+1)

즉시 로딩 시 query 예시
fetch join 예시

 

Lazy Loading & Eager Loading

3. 영속성 전이와 고아 객체

  • 영속성 전이: CASCADE 
    • 연관관계 매핑과는 관련이 없음
    • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속상태로 만들고 싶을 때 사용 => 연쇄작용
    • cascade = CascadeType.X
    • 종류
      • ALL : 모두 적용
      • PERSIST : 영속
      • REMOVE : 삭제
      • MERGE: 병합
      • REFRESH: 새로고침
      • DETACH : 준영속상태로 만듦
    • 주의사항
      • 엔티티가 단일 종속적인 경우 사용
      • 엔티티 라이프 사이클이 동일한 경우 사용
  • 고아객체
    • 부모 엔티티와 연관관계가 끊어진 자식 엔티티
    • orphanRemoval = true
    • 개념적으로 부모를 제거하면 자식은 고아가 되기 때문에 고아 객체 제거 기능 = CascadeType.REMOVE와 동일하게 동작
    • 주의사항
      • 참조하는 곳이 하나일 때 사용
      • 특정 엔티티가 개인 소유할 때 사용

정리

  • CascadeType.ALL + orphanRemovel=true
  • 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
  • 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있음
  • 도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용
출처
인프런 - 자바 ORM 표준 JPA 프로그래밍 - 기본편(김영한님)

 

728x90

'프로그래밍공부(Programming Study) > JPA(Java Persistence API)' 카테고리의 다른 글

1. 영속성 관리  (0) 2022.12.28
5. 값 타입  (2) 2022.12.28
JPA 공부 개요  (0) 2022.12.28

댓글