1. 지연로딩, 즉시로딩
-연관관계 조회시 지연로딩 LAZY를 사용해서 프록시로 조회한다
Member에있는 team 객체는 TEAM_ID로 외래키로 조회한다.
만약 이 객체를 사용하지 않는다면 프록시에 team을 담아 놓고, team을 사용하는 그때 db에서 해당 정보를 조회한다(사용하는 시점에 초기화)
m.getTeam().getName(): 이때 초기화가 발생한다
-지연로딩이 아닌 즉시로딩(EAGER)을 사용한 경우
Member 조회시 항상 Team도 조회된다. member 조회 쿼리가 나가면 반드시 team 조회 쿼리도 나감
-프록시와 즉시로딩에 대해 주의할 점
가급적 실무에서는 지연 로딩만 사용한다!
즉시 로딩을 적용하면 예상하지 못한 SQL이 발생하고
즉시로딩은 JPQL에서 N+1 문제를 일으킨다(team 하나(1)를 조회하면 그거에 해당하는 멤버 N을 조회하는 경우-> N+1)
@ManyToOne, @OneToOne은 기본이 즉시 로딩이므로 fetch=FetchType.LAZY로 설정하기
@OneToMany, @ManyToMany는 기본이 지연로딩이다
-지연로딩을 사용하는 경우를 구분하면
다대일 관계에서 참조하는 객체를 가끔 사용한다면 지연로딩을,
자주 사용한다면 즉시로딩을 하면된다.
참조하는 객체를 항상 사용하지 않는 경우 -> 지연로딩
지연로딩을 하면 연관된 걸 프록시로 가져온다
위 엔티티 관계에서
Member/Order 가끔 사용 -> 지연로딩
Order/Product 자주 사용 -> 즉시로딩
Member/Team 자주 사용 -> 즉시로딩
-실무에서 지연로딩 활용
모든 연관관계에서 지연 로딩을 사용해라!
실무에서 즉시 로딩을 사용하지마라! 즉시 로딩은 상상하지 못한 쿼리가 나간다
JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라
값 타입 컬렉션들은 기본으로 지연로딩
궁금한점,알아봐야할 것:
처음에 엔티티로 조회했으면 이후에 프록시로 해도 디비에서 가져온다 (엔티티를 가져오는 건가?)
처음에 reference로 조회했으면 이후에 엔티티 조회해도 프록시를 가져온다?
2.영속성 전이: CASCADE
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다
예시: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장(1:n)
-Cascade를 설정하지 않는다면, 부모/자식 객체 모두 일일이 persist,remove 해줘야한다
-또한 부모/자식이 양방향 연관관계인 경우 하나의 값이 변경되면 연관된 객체에도 값 변경을 해줘야한다.
(다음 사진은 연관관계 메소드를 작성해서 두 곳에 변경된 값을 입력하는 경우이다)
-주의할 점!
영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다
엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐이다
단일 엔티티에 종속될 때만 cascade 사용할 수 있다. 엔티티가 다른 엔티티와 연관되어 있다면 cascade 사용하면 안됨
-cascade를 사용하는 경우
1) parent,child의 라이프 사이클이 유사할 때
2) 단일 소유자일 때
-종류: ALL(모두 적용),PERSIST(영속),REMOVE(삭제)를 주로 사용한다
3. 고아객체
고아 객체 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 의미한다
고아 객체 제거: 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 제거한다
orphanRemoval=true
-주의
참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아객체로 보고 삭제하는 기능이므로 참조하는 곳이 하나일 때 사용해야한다!
특정 엔티티가 개인 소유할 때 사용 가능하다
@OneToOne, @OneToMany만 가능하다
-참고
개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화하면(orphanRemoval=true), 부모를 제거할 때 자식도 제거된다. 이것은 CascadeType.Remove처럼 동작한다
4. 영속성 전이+고아객체, 생명주기
CascadeType.ALL+orphanRemoval=True
orphanRemoval=True: 부모 객체를 삭제하면 자식 객체가 고아가되는데, 그러한 고아객체 삭제를 활성화한다(CascadeType.Remove처럼 행동한다)
여기서 CacadeType.ALL을 추가하면 부모 엔티티를 통해서 자식의 생명주기도 관리할 수 있다.
도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용하다
궁금한점: orphanRemoval=True가 CascadeType.Remove처럼 행동하는데 CascadeType.ALL을 추가하는 이유는
Persist같은 연산도 영속하기 위해서인건가?
갑자기 궁금해져서 찾아본거
클래스,객체,인스턴스의 차이
클래스는 어떠한 변수와 메소드를 가지는 명세서,설계도
객체는 우리가 클래스로 구현할 어떤 것
인스턴스는 객체를 실체화 시킨 것
'JPA' 카테고리의 다른 글
[JPA] 2/24 공부내용 기록(조인,on 절, 서브쿼리) (0) | 2022.02.26 |
---|---|
[JPA] 2/22 공부 내용 기록(값타입,Embedded Type) (0) | 2022.02.25 |
[JPA] 2/20 공부내용 기록(프록시) (0) | 2022.02.21 |
[JPA] 2/20 공부내용 정리(테이블 조인/단일 테이블 전략, @MappedSuperclass) (0) | 2022.02.21 |
[JPA] 2/17 공부내용 정리 (다대일, @ManyToOne) (0) | 2022.02.21 |