[데브코스] JPA - Proxy + 영속성전이

Updated: Categories:

W8D3 Part3 - Proxy / 영속성 전이 / 고아객체에 대해 알아보자

Proxy

  • Entity는 객체가 데이터베이스(RDB)와 매핑되어 있어서 자유롭게 객체를 탐색하는데 제한이 있다.
  • JPA는 프록시객체라는 기술을 사용하여 연관된 객체를 처음부터 데이터베이스에서 조회하지 않고, 실제 사용하는 시점에 조회할 수 있다.
    • fetch 전략에 따라 다르게 구현한다.

특징

  • 프록시 객체는 처음 사용할 때 한번만 초기화 된다.
  • 프록시 객체가 초기화되면, 프록시 객체를 통해서 실제 엔티티에 접근 할 수 있다.
  • 초기화는 영속성 컨텍스트의 도움을 받아야 가능하다. 따라서 준영속 상태의 프록시를 초기화하면 LazyInitializationException 예외가 발생한다.

Lazy - 지연로딩

  • 엔티티가 영속화될때 해당 엔티티 내의 연관관계 엔티티를 바로 DB에서 가져오지 않음 (영속화되지 않음)
    • 연관관계 엔티티실제로 사용될때 DB에서 정보를 가져와 영속화시킨다.
class Member {
	...
	// Member 엔티티가 영속화될때 Order 엔티티까지 영속화시키지 않음
	@OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
	private List<Order> orders;
}

class Order {
	...
	@ManyToOne
	@JoinColumn(name = "member_id", referencedColumnName = "id")	
	private Member member;
}

image

Eager - 즉시로딩

  • 엔티티가 영속화될때 해당 엔티티 내의 연관관계 엔티티를 즉시 DB에서 가져온다.
    • 해당 엔티티의 연관관계 엔티티를 모두 영속화 시켜버림
  • 하지만 가급적 개발환경에서만 사용하자. (비용이 큼)
class Member {
	...
	// Member 엔티티가 영속화될때 Order 엔티티까지 영속화
	@OneToMany(mappedBy = "member", fetch = FetchType.EAGER)
	private List<Order> orders;
}

class Order {
	...
	@ManyToOne
	@JoinColumn(name = "member_id", referencedColumnName = "id")	
	private Member member;
}

image


CASCADE - 영속성 전이

  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속성 상태로 만들고 싶을 때.
  • EAGER 로딩과의 차이점 :
    • EAGER : 조회할때 사용
    • CASCADE : 뭔가 추가할 때 사용
  • 연관관계 어노테이션에 cascade = CascadeType.타입종류를 넣어주면 됨

종류

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


고아 객체

  • 고아 객체란? -> 부모 엔티티와 연관관계가 끊어진 자식 엔티티
  • 어딘가에 참조되고 있다면 고아 객체가 아니다. -> 참조하는 곳이 하나일 때 사용해야함
    • @OneToMany, @OneToOne 인 곳에서 사용
  • 고아 객체를 어떻게 처리할지는 연관관계 어노테이션에 orphanRemoval = true/false를 추가해서 정해준다.
    • true : flush 고아 객체를 DB에서 삭제