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같은 연산도 영속하기 위해서인건가?

 

갑자기 궁금해져서 찾아본거 

클래스,객체,인스턴스의 차이

클래스는 어떠한 변수와 메소드를 가지는 명세서,설계도

객체는 우리가 클래스로 구현할 어떤 것 

인스턴스는 객체를 실체화 시킨 것 

+ Recent posts