본 글은 김영한님의 <자바 ORM 표준 JPA 프로그래밍>을 읽고 공부한 내용을 정리한 글입니다.
- 프록시
- 즉시 로딩과 지연 로딩
- 영속성 전이 : CASCADE
- 고아 객체
- 영속성 전이 + 고아 객체, 생명주기
연관된 객체를 마음껏 탐색하기 위해서 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스를 조회하는 프록시를 사용한다.
➡ 엔티티가 실제 사용될 때까지 데이터베이스 조회를 지연하는 방법
지연 로딩을 하기 위해서는 EntityManager.getReference()
메소드를 사용한다.
위의 메소드를 호출하면 JPA는 데이터베이스 접근을 위임한 프록시 객체를 반환한다.
프록시
EntityManager.getReference()
를 호출해도 프록시가 아닌 실제 엔티티를 반환한다.프록시 객체의 초기화
➡ 프록시 객체는 member.getName()
처럼 실제 사용될 때 데이터베이스를 조회해서 실제 엔티티 객체를 생성한다.
연관된 엔티티의 조회 시점을 선택하는 방법에는 즉시 로딩과 지연 로딩이 있다.
하나씩 알아보자.
➡ 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
설정 : @ManyToOne(fetch = FetchType.EAGER)
대부분의 JPA 구현체는 즉시 로딩을 최적화하기 위해 가능하면 조인 쿼리를 사용한다.
➡ 연관된 엔티티를 실제 사용할 때 조회한다.
설정 : @ManyToOne(fetch = FetchType.LAZY)
조회 대상이 영속성 컨텍스트에 이미 있으면 프록시 객체를 사용할 이유가 없다.
왜냐하면 조회대상이 영속성 컨텍스트에 없어야 DB를 조회하는 것이고, 프록시의 목적은 DB 조회의 지연이기 때문이다.
JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다.
귀찮게 하나하나 저장하지 않아도 부모 엔티티를 저장하면 자식 엔티티도 함께 저장되는 방법이다.
영속성 전이 : 저장
설정 : cascade = CascadeType.PERSIST
영속성 전이 : 삭제
설정 : cascade = CascadeType.REMOVE
➡ 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능
참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제한다.
따라서 이 기능은 참조하는 곳이 하나일 때에만 사용해야 한다.
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);