프록시
: 엔티티의 지연 로딩을 관리하기 위해 사용하는 객체
언제 프록시를 사용하는가?
➜ 테이블을 조회할 때, 연관관계 객체는 필요하지 않은 경우
연관되어 있는 객체를 함께 조회하려면, Join을 사용해서 테이블을 함께 조회해야 한다.
➜ 쿼리가 복잡해진다.
따라서, 비즈니스 로직에서 연관관계 객체가 필요하지 않다면 프록시를 사용한다.
em.find()
는 실제 엔티티를 조회하는 메소드이고, em.getReference
를 사용하면 프록시를 조회할 수 있다.⚠️ 영속성 컨텍스트에 엔티티가 이미 존재하면, em.getReference
를 호출해도 실제 엔티티를 반환한다.
프록시 초기화란?
: 프록시 객체가 처음으로 실제 엔티티의 데이터에 접근할 때 발생하는 과정
Issue issue1 = em.getReference("Issue.class","issue1");
issue1.getTitle();
em.getReference("Issue.class","issue1");
를 호출하면, 프록시 객체인 IssueProxy
를 반환한다.
issue1.getTitle();
를 호출하면, 실제 엔티티를 호출해야 한다.
엔티티가 생성되지 않았다면, 영속성 컨텍스트에 초기화 요청을 한다.
영속성 컨텍스트는 DB에서 Issue 엔티티를 조회한다.
IssueProxy
객체는 참조를 통해 Issue
객체의 getTitle()
함수를 호출한다.
⚠️ 프록시 객체가 준영속 상태인 경우, 프록시를 초기화하면 오류가 발생한다!
엔티티를 조회할 때 해당 엔티티의 연관된 엔티티들도 함께 즉시 로드하는 전략
@JoinColumn(fetch = FetchType.EAGER)
를 사용한다.@ManyToOne
, @OneToOne
은 기본 값이 즉시 로딩이다.education_content
테이블은 menu_id 를 FK로 가지고 있다.
만약, @JoinColumn(fetch = FetchType.EAGER)
로 설정되어 있다면, education_content를 조회할 때 항상 menu도 함께 조회한다.
엔티티를 실제로 필요로 할 때까지 연관된 엔티티의 로딩을 지연시키는 전략
@JoinColumn(fetch = FetchType.LAZY)
를 사용한다.@OneToMany
, @ManyToMany
는 기본 값이 지연 로딩이다.education_content
테이블은 menu_id 를 FK로 가지고 있다.
만약, @JoinColumn(fetch = FetchType.LAZY)
로 설정되어 있다면, education_content를 조회할 때 menu는 프록시 객체로 조회된다!
영속성 전이 (CASCADE)
: 한 엔티티에 대한 변경이 연관된 다른 엔티티에 자동으로 반영되는 기술
부모 엔티티와의 관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능
Orphan Removal은 @OneToOne
, @OneToMany
에서만 사용 가능하다.
CascadeType.ALL
, orphanRemoval = true
속성을 함께 사용하면, 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있다.