[JPA] 8장 프록시와 연관관계 정리

diveintoo·2022년 3월 10일
0

본 글은 김영한님의 <자바 ORM 표준 JPA 프로그래밍>을 읽고 공부한 내용을 정리한 글입니다.

  1. 프록시
  2. 즉시 로딩과 지연 로딩
  3. 영속성 전이 : CASCADE
  4. 고아 객체
  5. 영속성 전이 + 고아 객체, 생명주기

연관된 객체를 마음껏 탐색하기 위해서 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스를 조회하는 프록시를 사용한다.

1. 프록시

1.1 지연 로딩

➡ 엔티티가 실제 사용될 때까지 데이터베이스 조회를 지연하는 방법

  • 프록시 객체 : 지연 로딩 기능을 사용하기 위해 실제 엔티티 객체 대신 사용하는 가짜 객체

1.2 프록시 기초

  • 지연 로딩을 하기 위해서는 EntityManager.getReference() 메소드를 사용한다.

  • 위의 메소드를 호출하면 JPA는 데이터베이스 접근을 위임한 프록시 객체를 반환한다.

  • 프록시

    • 프록시 객체는 실제 객체에 대한 참조를 보관한다.
    • 프록시 객체의 메소드를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.
    • 프록시 객체는 처음 사용할 때 한 번만 초기화된다.
    • 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 데이터베이스를 조회할 필요가 없으므로 EntityManager.getReference()를 호출해도 프록시가 아닌 실제 엔티티를 반환한다.
  • 프록시 객체의 초기화
    ➡ 프록시 객체는 member.getName() 처럼 실제 사용될 때 데이터베이스를 조회해서 실제 엔티티 객체를 생성한다.

2. 즉시 로딩과 지연 로딩

연관된 엔티티의 조회 시점을 선택하는 방법에는 즉시 로딩과 지연 로딩이 있다.
하나씩 알아보자.

2.1 즉시 로딩

➡ 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
설정 : @ManyToOne(fetch = FetchType.EAGER)

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

2.2 지연 로딩

➡ 연관된 엔티티를 실제 사용할 때 조회한다.
설정 : @ManyToOne(fetch = FetchType.LAZY)

조회 대상이 영속성 컨텍스트에 이미 있으면 프록시 객체를 사용할 이유가 없다.
왜냐하면 조회대상이 영속성 컨텍스트에 없어야 DB를 조회하는 것이고, 프록시의 목적은 DB 조회의 지연이기 때문이다.

3. 영속성 전이 : CASCADE

JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다.
귀찮게 하나하나 저장하지 않아도 부모 엔티티를 저장하면 자식 엔티티도 함께 저장되는 방법이다.

  • 영속성 전이 : 저장
    설정 : cascade = CascadeType.PERSIST

  • 영속성 전이 : 삭제
    설정 : cascade = CascadeType.REMOVE

4. 고아 객체

➡ 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능

참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제한다.
따라서 이 기능은 참조하는 곳이 하나일 때에만 사용해야 한다.

5. 영속성 전이 + 고아 객체, 생명주기

CascadeType.ALL + orphanRemoval = true를 동시에 사용하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있다.

  • 자식을 저장하려면 부모에 등록만 하면 된다.
    Parent parent = em.find(Parent.class, parentId);
     parent.addChild(child1);
  • 자식을 삭제하려면 부모에서만 제거하면 된다.
    Parent parent = em.find(Parent.class, parentId);
     parent.getChildren().remove(child1);

0개의 댓글