자바 ORM 표준 JPA 프로그래밍 - 프록시, 영속성전이, 고아객체

lacblueeun·2021년 1월 9일
0

springboot

목록 보기
12/17
post-thumbnail

1. 프록시

객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다. JPA는 이 문제를 해결하려고 프록시라는 기술을 사용한다. 프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다.

Member member = em.find(Member.class, "member1");
Member member = em.getReference(Member.class, "member1");

em.find() : 엔티티를 직접 조회하면 조회한 엔티티를 실제로 사용하든 사용하지 않든 데이터베이스를 조회한다.

em.getReference() : 엔티티를 실제 사용하는 시점까지 데이터베이스 조회를 미루고 싶으면 사용한다. 실제 객체도 생성하지 않고, 데이터베이스 접근을 위임한 프록시 객체를 반환한다.

1-1 프록시의 특징

프록시 클래스는 실제 클래스를 상속 받아서 만들어지므로 실제 클래스와 모양이 같다. 프록시 객체는 실제 객체의 참조(target)를 보관한다.(실제 객체의 메소드를 호출한다.)

  1. 프록시 객체는 처음 사용할 때 한 번만 초기화된다.
  2. ✨ 프록시 객체는 원본 엔티티를 상속받은 객체이므로 타입 체크 시에 주의
  3. 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태의 프록시를 초기화하면 문제가 발생한다.
  4. ✨✨ transaction 도 함께 끝나면 프록시 조회할 때, no session 이라는 오류를 만나게 된다.

org.hibernate.Hibernate.initialize(entity); : 프록시 강제로 초기화
PersistenceUnitUtil.isLoaded(Object entity) : 프록시 인스턴스의 초기화 여부

2. 지연로딩

프록시 객체는 실제 사용될 때까지 데이터 로딩을 미룬다. 만약 조회 대상이 영속성 컨텍스트에 이미 있으면 프록시 객체를 사용할 이유가 없다. 따라서 실제 객체를 사용한다.
@ManyToOne(fetch = FetchType.LAZY)

3. 즉시로딩

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

영한님 : 하지만 실무에서 절대 즉시 로딩을 사용하지 마라! fetch 또는 엔티티 그래프를 이용하자! 예상치 못한 쿼리를 볼 수 있다.

4. 영속성 전이 (CASCADE)

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 영속 상태로 만들고 싶을때 사용한다.
JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다.
하나의 부모가 자식들을 관리할 때, 사용하는 것이 좋다.
(게시글 하나에 첨부파일 경로 등등)

@OneToMany(cascade = CascadeType.ALL) :영속성 전이는 연관관계를 매핑하는 것과는 아무 관련이 없다. 단지 엔티티를 영속화 할 때 연관된 엔티티도 같이 영속화하는 편리함을 제공한다.

Parent 앤티티만 영속화하면 Child 엔티티도 데이터베이스에 입력된 것을 확인할 수 있다.

5. 고아 객체

JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공한다. 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티가 자동으로 삭제된다.

CASCADE + orphanRemoval 을 통해서 자식의 생명주기를 관리할 수 있다.

profile
Go for Frontend Developer 🧪

0개의 댓글