ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 03. JPA 연관관계 관리
    BackEnd/JPA 2021. 8. 13. 14:48
    반응형

    1. 즉시 로딩(EAGER)과 지연 로딩(LAZY)

      > Member Entity : Team Entity ( N : 1 )가 존재할 때 즉시 로딩은 두 엔티티를 한 번에 조회하지만 지연 로딩은 프록시로 조회한다.

      > 즉시 로딩은 JPQL에서 N+1 문제를 야기하기 때문에 실무에서는 가급적 지연 로딩만 사용한다. JPQL fetch 조인이나 엔티티 그래프 기능을 사용하는 것이 좋다.

        (@OneToMany, @ManyToMany는 기본이 지연 로딩이다. @ManyToOne, @OneToOne은 기본이 즉시 로딩이기에 LAZY로 설정한다.)

     

    tip) 프록시(Proxy)

      > em.find(): 데이터베이스를 통해서 실제 엔티티 객체 조회
      > em.getReference(): 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회

      > PersistenceUnitUtil.isLoaded(Object entity): 프록시 인스턴스의 초기화 여부 확인

      > entity.getClass().getName() 출력(..javasist.. or HibernateProxy…): 프록시 클래스 확인 방법

      > org.hibernate.Hibernate.initialize(entity): 프록시 강제 초기화 (JPA 표준은 강제 초기화 없음)

     

      (Proxy 특징)

      1) 프록시 객체는 실제 객체의 참조(target)를 보관(상속), 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.

      2) 프록시 객체를 초기화 할 때 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근이 가능하다.

      3) 프록시 객체 타입 비교 시 == 대신 instance of를 사용한다.

      4) 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해도 실제 엔티티를 반환한다.

      5) 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제가 발생한다.
         (하이버네이트는 org.hibernate.LazyInitializationException 예외)

     

    [즉시 로딩]

    @Entity

    public class Member {

      @Id @GeneratedValue

      private Long id;

      ..

      @ManyToOne(fetch = FetchType.EAGER)

      @JoinColumn(name = "TEAM_ID")

      private Team team;

      ..

    }

     

    [지연 로딩]

    @Entity

    public class Member {

      @Id @GeneratedValue

      private Long id;

      ..

      @ManyToOne(fetch = FetchType.LAZY)

      @JoinColumn(name = "TEAM_ID") private Team team;

      ..

    }

     

    2. 영속성 전이(CASCADE)

      > 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다. 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다.

         @OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)

      > CASCADE 종류

         (ALL: 모두 적용, PERSIST: 영속, REMOVE: 삭제, MERGE: 병합, REFRESH: REFRESH, DETACH: DETACH)

     

    3. 고아 객체

      > 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능으로 참조하는 곳이 하나일 때 사용해야 한다. @OneToOne, @OneToMany만 가능하다. (orphanRemoval = true)

      > CascadeType.ALL + orphanRemovel=true : 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있다. 도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용하다.

     

    반응형

    'BackEnd > JPA' 카테고리의 다른 글

    05. JPA 객체지향 쿼리 언어(JPQL)  (0) 2021.08.13
    04. JPA 값 타입  (0) 2021.08.13
    02. JPA Mapping Annotation  (0) 2021.08.09
    01. JPA(Java Persistence API)  (0) 2021.08.09

    댓글

Designed by Tistory.