프록시
em.find
- DB를 통해서 실제 엔티티 객체 조회
em.getReference
- DB 조회를 미루는 가짜 객체(프록시) 엔티티 객체 조회
특징
- 실제 클래스를 상속받아서 만들어진다.
- 실제 클래스와 겉모양이 같다.
- 사용하는 입장에서 이론상으로 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다.
- 프록시 객체는 실제 객체의 참조(target)를 보관
- 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메서드를 호출한다.
-
- 프록시 객체는 처음 사용할 때 한번만 초기화
- 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 변하는게 아님
- 초기화 시, 프록시 객체를 통해서 실제 엔티티로 접근이 가능한 것
- 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입을 체크해야한다.
- (== 비교가 아닌 instance of를 사용할 것)
- 영속성 컨텍스트에 이미 찾고자 하는 엔티티가 있을 경우, getReference를 해도, 프록시 객체가 아닌 실제 엔티티 반환
- 영속성 컨텍스트의 통제에서 벗어난 준영속(detached)상태일 경우, 프록시를 초기화하면 문제 발생
- 하이버네이트는 org.hibernate.LazyInitializeException 예외 발생
프록시 인스턴스의 초기화 여부 확인
- PersistenceUnitUtil.isLoaded(Object entity)
프록시 클래스 확인 방법 - entity.getClass().getName() 출력
프록시 강제 초기화 - org.hibernate.Hibernate.initialize(entity);
참고사항 - JPA 표준은 강제 초기화 없음
- 강제 호출 : member.getName()과 같이 호출을 통해서 초기화 할 수 있다.
즉시로딩과 지연로딩
지연로딩
즉시로딩
주의사항
- 가급적 모든 연관관계에서 지연로딩을 사용할 것
- 즉시 로딩을 적용하면 예상치 못한 SQL이 발생
- 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
- @ManyToOne, @OneToOne은 기본이 즉시로딩이다.
- 지연로딩으로 변경할 것
- @OneToMany, @ManyToMany는 기본이 지연로딩이다.
- 실무에서의 주의사항
- JPQL fetch 조인이나, 엔티티 그래프 기능을 사용할 것
영속성 전이 (Cascade)
사용시기
- 특정 엔티티를 영속상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때
- 예) 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장
주의사항
- 영속성 전이는 연관관게를 매핑하는 것과 아무 관련이 없음
- 엔티티를 영속화할 때 연관된 엔티티를 함께 영속화하는 편리함을 제공할 뿐이다.
종류
- ALL : 모두 적용
- PERSIST : 영속
- REMOVE : 삭제
- MERGE : 병합
- REFRESH : REFRESH
- DETACH : DETACH
고아객체
고아객체 제거
- 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
- orphanRemoval = true
- Parent parent1 = em.find(Parent.class, id);
- parent1.getChildren().remove(0);
- 결과는 자식엔티티가 컬렉션에서 제거된다.
- delete from child where id = ?
- orphanRemoval = true
주의사항
- 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
- 참조하는 곳이 하나일 때 사용해야한다.
- 특정 엔티티가 개인 소유할 때 사용
- @OneToOne, @OneToMany만 사용 가능
- 참고사항
- 개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화 하면, 부모 제거시 자식도 함께 제거된다. 이것은 CascadeType.REMOVE와 같이 동작한다.
영속성 전이 + 고아 객체, 생명주기
CascadeType.ALL + orphanRemoval = true
- 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
- 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있음
- 도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용
728x90
'Java' 카테고리의 다른 글
JPA 기본 - 연관관계 매핑 (1) | 2024.06.08 |
---|---|
JPA 기본 - 영속성 컨텍스트 (0) | 2024.06.05 |