본 내용은 인프런 김영한 강사님 JPA 기본 편 강의를 듣고 정리한 내용입니다.
https://www.inflearn.com/course/ORM-JPA-Basic
자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 - 인프런
현업에서 실제로 JPA로 개발을 하고 있습니다. 그런 입장에서보면 지금 작성하고 있는 코드들이 어떻게 작동하는지 이해하는데 큰 도움을 주는 강의입니다. 다음은 제가 느낀 이 강의의 장점들
www.inflearn.com
이제 본격적으로 Member를 조회할 때 Team까지 조회할 필요가 없을 때 어떻게 해야 하는지 지연로딩을 배우면서 알아보자
지연로딩
연관된 엔티티를 사용하는 시점에서 조회가 발생하는 것을 말한다.
지연로딩 하는 방법은 연관관계 매핑에서 fetch를 LAZY로 정해주면된다. (아래에서 추후 다시 다룰 예정이다)
이렇게 하게 되면 member에서 팀을 가져와서 직접적으로 사용하기 전까지 Team은 프록시 객체로 되어있다.
위 결과처럼 Team을 직접적으로 사용하지 않기때문에 쿼리문을 보면 team에 관한 것은 조회되지 않고 Team 역시 프록시 객체로 출력되는 것을 알 수 있다.
위 결과에서 보이는 것과 같이 findMember.getTeam().getName()을 하는 순간 이때 select쿼리가 발생하고, teamA의 이름이 나오는 것을 알 수 있다.
만약 Member와 Team을 자주 함께 사용한다면
fetch = FetchType.EAGER로 바꿔주면 된다. (알고만 있으면 된다)
위와 같이 EAGER로 바꿔주는 방법을 즉시로딩 이라고 한다.
그러나 즉시로딩은 같이 자주 사용하게 되는 경우 이론상 유용하지만 실무에서는 반드시!!즉시로딩은 사용하지 않고 지연로딩만 사용해야 한다.
즉시로딩 주의점
1. 즉시 로딩을 적용하면 예상 하지 못한 SQL이 발생한다 -> 실제 협업에서는 수많은 테이블이 연관관계로 매핑되어 있는데 Member 하나 가져오는데 수십 개 테이블 조회가 발생할 수 있다.
2. 즉시로딩은 JPQL에서 N + 1 문제를 일으킨다.
3. @ManyToOne, @OnToOne은 기본이 즉시로딩 이기 때문에 반드시 LAZY로 바꿔줘야 한다. @OneToMany @ManyToMany는 기본이 지연로딩이다.
즉시로딩 대신 JPQL fetch 조인이나 엔티티 그래프 기능을 이용하자!
영속성 전이(CASCADE)
특정 엔티티를 영속 상태로 만드는 과정에서 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다.
이때 주의해야 할 점은 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없고, 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함만 제공해 주는 것이다.
위 사진과 같이 Parent와 Child관계일 때 영속성 전이를 하지 않았을 경우 아래 코드와 같이 persist()를 3번 호출해야 한다.
영속성 전이를 사용하게 된다면 persist(parent)를 하면 자동으로 자식도 persist()가 된다.
영속성 전이를 했기 때문에 child를 persist()를 하지 않고 parent만 persist()를 해도 child의 persist가 동작하는 것을 알 수 있다.
CASCADE의 종류로는 여러 가지가 있는데 그중에서 3가지만 확인해 보자
- ALL: 모두 적용
- PERSIST: 영속
- REMOVE: 삭제(게시판 같은 하나에만 상속되어 있는 것만 해야 한다. 다른 테이블과 연결되어 있는 건 잘못 삭제하면 안 된다)
고아 객체
부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
orphanRemoval = true 이걸 사용하면 관련된 엔티티 역시 삭제된다.
따로 remove()를 사용하지 않아도 child가 삭제되는 것을 볼 수 있다.
CascadeType.ALL + orphanRemoval=true
두 옵션을 모두 활성화해놓으면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있다.
이러한 방식은 도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용하다.
'JAVA & SPRING > JPA' 카테고리의 다른 글
JPA0 기본편(값 타입과 불변 객체, 값 타입 컬렉션) (0) | 2024.03.04 |
---|---|
JPA 기본편0(값 타입 {기본값 타입, 임베디드 타입}) (0) | 2024.03.04 |
JPA 기본편(프록시) (0) | 2024.03.04 |
JPA 기본편0(연관관계 매핑 기초, 연관관계가 필요한 이유 & 연관관계 매핑) (0) | 2024.02.23 |
JPA 기본편0 (기본키 매핑) (0) | 2024.02.20 |