프록시
프록시란?
- 실제 엔티티 객체 대신 데이터베이스 조회를 지연하게 하는 가짜 객체
- 지연 로딩(엔티티가 실제 사용되는 시점에 데이터베이스 조회)을 가능하게 한다.
프록시의 특징
- 실제 클래스를 상속 받아 만들어졌다. → 실제 클래스와 겉모양이 같다.
- 실제 객체에 대한 참조를 갖고 있다.
- 초기화 : 영속성 컨텍스트에 실제 엔티티를 생성하라고 요청한다.
- 처음 사용할 때 한 번만 초기화된다.
- 초기화되면 프록시 객체를 통해 실제 엔티티에 접근할 수 있다.
- 초기화를 하려면 영속 상태여야 한다.
- 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 프록시가 아닌 실제 엔티티를 반환한다.
프록시 초기화 과정
- 프록시 객체에
member.getName()
을 호출한다.
- 영속성 컨텍스트에 찾는 엔티티가 있으면, 실제 엔티티를 반환한다.
- 없으면, 영속성 컨텍스트에 실제 엔티티를 생성하라고 요청한다. (초기화)
- 영속성 컨텍스트가 데이터베이스를 조회해서 실제 엔티티 객체를 만든다.
- 프록시 객체는 생성된 실제 엔티티 객체의 참조를 프록시 멤버변수에 보관한다.
- 프록시 객체는 실제 엔티티 객체의
getName()
을 호출해서 결과를 반환한다.
즉시 로딩과 지연 로딩
즉시 로딩(Eager Loading)
- @ManyToOne(fetch = FetchType.EAGER)
- 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
- 하이버네이트는 가능하면 SQL 조인을 사용해서 한 번에 조회한다.
지연 로딩(Lazy Loading)
- @ManyToOne(fetch = FetchType.LAZY)
- 연관된 엔티티를 실제 사용할 때 조회한다.
- 조회한 엔티티를 실제 사용하는 시점에 JPA가 SQL을 호출해서 엔티티를 조회한다.
- 지연 로딩 설정된 객체를 호출하면 프록시 객체를 반환한다. 실제 사용될 때까지 데이터 로딩을 미룬다.
- 프록시를 실제 사용할 때 초기화하면서 데이터베이스를 조회한다.
JPA 기본 전략
- @ManyToOne, @OneToOne : 즉시 로딩
- @OneToMany, @ManyToMany : 지연 로딩
- 엔티티가 하나면 즉시 로딩
- 컬렉션이면 지연 로딩
- 추천 방법 : 모든 연관관계 지연 로딩 → 실제 사용 상황 보고 꼭 필요한 곳에만 즉시 로딩
영속성 전이 : CASCADE
- 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만든다.
- 객체를 저장하거나 삭제할 때 연관된 객체도 함께 저장하거나 삭제할 수 있다.
- JPA에서 엔티티를 저장할 때 연관된 모든 엔티티가 영속 상태여야 하는데, 영속성 전이를 사용하면 부모만 영속 상태로 만들면 연관된 자식까지 한번에 영속 상태로 만들 수 있다.
- CascadeType.PERSIST : 부모 엔티티가 영속 상태가 되면 자식 엔티티도 함께 영속 상태가 된다.
- CascadeType.REMOVE : 부모 엔티티만 삭제하면 자식 엔티티도 함께 삭제 할 수 있다.
[참고자료]
<자바 ORM 표준 JPA 프로그래밍>