엔티티 조회시 늘 연관된 데이터가 사용되는 것은 아니다.
그렇다면 가-나-다 로 연관이 맺어져 있는 엔티티가 있을때 가 를 조회시 나- 다를 사용하지 않는데
전부다 불러오는게 맞는 것일까?
→ 이는 서버에 부하를 주게 되는 행위이다 따라서 이를 예방하기 위해 지연로딩, 즉시로딩, 프록시가 존재한다.
그렇다면 프록시는 무엇일까?
프록시란 지연로딩 사용중 실제 엔티티 객체 대신 데이터 베이스 조회를 지연시킬수 있게 도와주는 가짜 객체를 프록시라 한다.
Member member = em.find(Member.class, "member1");
위와 같이 member를 조회하는 경우 member와 Team이 연관관계가 있다면 지연로딩을 하지 않을 경우에는 Team의 사용여부와 상관 없이 Team까지 같이 불러오게 된다.
이를 프록시를 사용하여 사용 시점까지 조회를 미루고 싶다면 다음 코드를 사용하면 된다.
Member member = em.getReference(Member.class, "member1");
프록시 클래스는 실제 클래스를 상속 받아서 생성되므로 실제 클래스와 겉 모습이 같다.
→ 사용자는 가짜 객체인지 진짜 객체인지 신경쓰지 않고 사용해도 무방하다.
☝️ 프록시는 실제 객체에 대한 참조를 보관하기 때문에 프록시 객체 메소드를 호출하게 되면 실제 객체의 메소드를 호출하게 된다. 이를 초기화라고도 한다.
➕ 프록시 객체는 식별자 값을 가지고 있기때문에 team.getId()를 하여도 초기화가 되지 않는다.
➕PersistenceUnitUtil.isLoaded(Object entity) 메소드를 사용시 인스턴스 초기화 여부를 확인 가능.
LAZY LOADING을 사용하게 되면 회원 - 팀을 지연 로딩 설정시 회원을 조회 하게 되면 회원의 팀은 프록시 객체로 조회가 된다.
이는 사용하기 직전까지 프록시객체로 존재하며 사용시에 데이터 베이스를 조회해 초기화를 하게 된다.
(김영한 님은 즉시 로딩 보다 지연 로딩을 사용하는것을 추천한다고 하신다.)
특정 엔티티를 영속 상태로 만들시 연관된 엔티티를 같이 영속 상태로 만들고 싶다면 영속성 전이를 사용하면 된다.
CASCADE 옵션을 사용해 적용 가능하다
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
CascadeType.REMOVE
JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동 삭제하는 기능을 제공한다. 이를 고아 객체라고 한다.
@OneToMany(mappedBy = "parent", orphanRemoval = true)
두 옵션을 함께 설정시 부모 엔티티가 자식의 생명 주기를 관리가 가능하다.