즉시로딩 지연로딩 FetchType
- 연관관계 entity를 바로 가져오거나 (즉시로딩 / FetchType = Eager), 필요할 때 가져옴 (지연로딩 / FetchType = Lazy)
- 기본적으로 @OneToMany는 Lazy (가져올 값이 많으니까(리스트)필요할때),
- @ManyToOne은 Eager 이 default
- FetchType=lazy는 @Transactional 걸어줘야 함
- 지연로딩도 연속성 컨텍스트의 기능 중 하나
- 지연로딩된 entity의 정보를 조회할 땐 영속성 컨텍스트가 존재해야함
- 영속성 컨텍스트 존재하기 위해 트렌젝션이 적용되어야함
영속성 전이 Cascade
- 영속 상태의 Enity에서 수행되는 작업들이 연관된 entity까지 전파되는 상황
- cascade persist옵션으로 설정
- cascade: remove를 통해 연관 entity의 정보 (음식과 유저 정보) 한번에 삭제 가능
- Cacade옵션을 Persist와 Remove를 중복으로 설정할 수 있음
- cascade = {CascadeType.PERSIST, CascadeType.REMOVE}
🔽 User entity에 foode cascade persist 설정 코드
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this);// 외래 키(연관 관계) 설정
}
}
user entity의 연관 entity인 food와 연관관계를 설정할 때
cascade = CascadeType.PERSIST 설정
🔽 영속성전이 설정 이전 코드
@Test
@DisplayName("Robbie 음식 주문")
void test1() {
// 고객 Robbie 가 후라이드 치킨과 양념 치킨을 주문합니다.
User user = new User();
user.setName("Robbie");
// 후라이드 치킨 주문
Food food = new Food();
food.setName("후라이드 치킨");
food.setPrice(15000);
user.addFoodList(food);
Food food2 = new Food();
food2.setName("양념 치킨");
food2.setPrice(20000);
user.addFoodList(food2);
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
}
user repository와 food repository각각 save 해줘야함
🔽 영속성전이 설정 이후 코드
@Test
@DisplayName("영속성 전이 저장")
void test2() {
// 고객 Robbie 가 후라이드 치킨과 양념 치킨을 주문합니다.
User user = new User();
user.setName("Robbie");
// 후라이드 치킨 주문
Food food = new Food();
food.setName("후라이드 치킨");
food.setPrice(15000);
user.addFoodList(food);
Food food2 = new Food();
food2.setName("양념 치킨");
food2.setPrice(20000);
user.addFoodList(food2);
userRepository.save(user);
}
Cascade를 설정함으로서 직접 food entity객체를 영속 상태로 만들지 않아도 자동 저장 됨
User, Food, Food2를 세번 저장하는 코드에서
userRepository만 저장하는 코드로 바뀜
🔽 Cacade Remove
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this);// 외래 키(연관 관계) 설정
}
}
Cacade옵션을 Persist와 Remove를 중복으로 설정할 수 있음
OrphanRemoval 고아 Entity 삭제
- 연관 entity 삭제 기능
🔽 orphanRemoval True
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this);// 외래 키(연관 관계) 설정
}
}
user와 연관 entity인 food에 대하여 orphanRemoval = true 설정
CascadeType.REMOVE와 orphanRemoval=true 의 차이
CascadeType.REMOVE
- 부모 엔티티가 삭제될 때 연관 자식 엔티티도 함께 삭제
- Post가 삭제되면 관련 Comment도 함께 삭제
orphanRemoval=true
- 부모 엔티티와의 연관 관계가 끊어진 자식 엔티티를 자동으로 삭제
- 부모 엔티티의 컬렉션에서 자식 엔티티를 제거하면, 해당 자식 엔티티는 데이터베이스에서도 삭제
- Order와 OrderItem의 관계에서 특정 주문 항목을 제거하면, 해당 주문 항목이 데이터베이스에서도 삭제되어야 하는 경우에 사용
'Spring' 카테고리의 다른 글
[TIL] 240508 MongoDB 적용하기 | 채팅 DB MySQL에서 MongoDB로 변경 (0) | 2024.05.08 |
---|---|
[TIL] 240418 Spring Data JPA 페이징 및 정렬 | Pageable, PageableDefault (2) | 2024.04.18 |
[TIL] 240409 Entity 연간 관계 | 1:1 매핑, 단방향, 양방향 (0) | 2024.04.09 |
[TIL] 240408 RestTemplate | NaverOpenApi 검색 (0) | 2024.04.08 |
[TIL] 240407 SpringSecurity (0) | 2024.04.07 |