FetchType은 2가지 "LAZY"와 "EAGER"가 있고 각각 즉시로딩과 지연 로딩에 해당된다. 기본 값 즉 디폴트 값으로 @ManyToOne의 경우 EAGER가 설정되어있고, @OneToMany의 경우 LAZY로 설정이 되어 있다.
@OneToMany의 경우 List형태로 해당 엔티티가 여러개가 있을 수 있으므로 효율적으로 정보를 조회하기 위해서 LAZY로 지연로딩을 하게 되어있다.
지연로딩의 경우 필요한 시점에 정보를 불러온다.
@ManyToOne의 경우 일반 객체 타입으로 즉시 정보를 가져와도 무리가 없으므로 EAGER로 즉시 로딩을 하게 디폴트 값이 설정되어 있다.
즉시 로딩의 경우 조회할 때 연관된 모든 Entity의 정보를 즉시 가져온다. 만약 @OneToMany에 EAGER로 설정할 경우 조회를 할 때마다 엔티티 여러개가 있을 때 모든 정보를 가져오려고 하기 때문에 좋지 않다. -> 사실상 이렇게는 사용하지 않는다고 한다.
따라서 @ManyToOne 쪽의 기본은 EAGER 이지만 LAZY로 바꿀 경우 에러가 발생한다.
지연로딩(LAZY)이 된 Entity의 정보를 조회하려고 할 때 반드시 영속성 컨텍스트가 존재해야 한다.
'영속성 컨텍스트가 존재해야 한다' 라는 의미는 결국 '트랜잭션'이 적용되어있어야 한다라는 의미이다.
보통 @Transactional의 경우 Insert, Update, Delete 할때 사용하고 단순히 조회할 때에는 사용하지 않는다. 다만, ※ 지연로딩(LAZY)된 엔티티 정보를 조회하려 할때는 마찬가지로 사용을 해줘야 한다.
기존의 경우 addFoodList 매서드를 만든 다음에 food와, food2 객체를 foodRepository에 직접 save를 해줬어야 했다.
JPA에서는 이를 간편하게 처리하는 방법으로 영속성전이(Cascade)의 PERSIST 옵션을 제공한다.
영속성 전이란?
-> 영속 상태의 Entity에서 수행되는 작업들이 연관된 Entity까지 전파되는 상황을 뜻한다.
영속성 전이를 사용하여 해당 Entity를 저장할 때 연관된 Entity까지 자동으로 저장하기 위해서는 자동으로 저장하려 하는 연관된 Entity에 추가한 연관관계 어노테이션에 cascade = CascadeType.PERSIST 를 설정하면 된다.
이렇게 PERSIST 설정을 할 경우 다음과 같이 음식 Entity객체 food, food2를 영속 상태로 만들지 않아도 자동으로 잘 저장된다.
Robbie User가 탈퇴하면서 주문한 Order 객체들을 모두 삭제하려고 할 때 다음과 같이 진행할 수 있다.
이렇듯 먼저 User 객체에서
1. 지연로딩(LAZY)된 foodList를 deleteAll 매서드를 통해 모두 삭제한 후
2. userRepository.delte 매서드로 User 엔티티를 지워야 한다.
**JPA에서는 이를 간편하게 처리하는 방법으로 영속성전이(Cascade)의 REMOVE 옵션을 제공한다.
cascade = {CascadeType.PERSIST, CascadeType.REMOVE} 이렇게 중복으로 옵션을 설정할 수도 있다.
고객 Entity의 @OneToMany 애너테이션에 연관된 음식 Entity도 자동으로 삭제될 수 있도록 REMOVE 옵션을 추가한다.
해당 코드를 실행해보면 User 엔티티만 삭제했지만, foodList들도 모두 삭제됐음을 DB를 통해 확인할 수 있다.
정확히 연관되어있는 foodList들을 먼저 delete한 후 User를 delete하였다.