1. 프록시 기초
em.find() vs em.getReference()
- em.find() : 실제 엔티티 객체를 조회한다.
- em.getReference() :
- 가짜(프록시) 엔티티를 조회한다. (아직 쿼리가 나가지 않는다.)
- 실제 필요한 경우에 쿼리가 나간다.
em.getReference()
0. member = em.getReference(Member.class, id) 1. member.getName() 1.1 프록시 객체의 target이 null 이다. 2. 영속성 컨텍스트에 초기화 요청을 한다. 3. 영속성 컨텍스트는 DB 에서 해당 객체를 조회한다. 4. Entity를 실제로 생성한다. 5. 프록시는 target.getName() 을 호출한다. |
프록시 특징 (em.getReference())
- 처음 사용할 때 한 번만 초기화한다.
- 프록시 객체를 초기화할 때, 실제 엔티티로 바뀌는게 아니고, 접근이 가능한 것이다.
- 위의 그림에서 봤을 때, target에 Reference가 생기는 것이다.
- 프록시 객체는 원본 엔티티를 상속 (memberProxy extends Member) 받는다. 따라서 타입체크시 유의해야 한다.
- instanceof 를 사용해야 한다.
- 영속성 컨텍스트에 이미 엔티티가 존재하면 바로 엔티티를 반환한다. (프록시 객체가 아니다.)
- 준영속(detached) 상태일 때, 프록시를 초기화하면 문제가 발생 (LazyInitializationException)
2. 즉시 로딩과 지연 로딩
FetchType.LAZY :
- 연관관계에 묶여있는 객체를 프록시로 조회한다.
- 따라서 호출(초기화) 전 까지 쿼리가 날라가지 않는다.
FetchType.EAGER
- 연관관계에 묶여이쓴 객체 (엔티티 실체)를 로딩한다.
실무에서는 웬만하면 FetchType.LAZY 사용하자.
- EAGER 가 걸려있으면 예상치 못하게 SQL이 날라갈 수 있다.
- FetchType.EAGER 은 JQPL 에서 N+1 문제
3. CASCADE
특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속상태로 만들고 싶을 때 사용
옵션
- ALL : 모두 적용
- PERSIST : 영속
- REMOVE : 삭제
- MERGE
- REFRESH
- DETACH
언제 쓰느냐?
- 게시판 처럼 부모가 확실할 때(단일 엔터티에 확실하게 종속적일 때) + 라이프사이클이 거의 유사할 때
고아 객체
- 부모 엔티티와 연관관계가 끊어진 자식엔티티를 자동으로 삭제
- orphanRemoval = true 를 통해서 삭제
CascadeType.ALL + orphanRemoval = true
- 하위엔티티의 생명주기를 아예 부모가 관리함
- child는 repository가 필요없어짐
- DDD 에서 유용
'강의 정리 > 자바 ORM 표준 JPA' 카테고리의 다른 글
9. 기본 문법 (0) | 2021.01.02 |
---|---|
8. 값 타입 (0) | 2021.01.01 |
6. 고급 매핑 (0) | 2020.12.29 |
5. 다양한 연관관계 매핑 (0) | 2020.12.28 |
4. 연관관계 매핑 기초 (0) | 2020.12.27 |