orphanRemoval
- CASCADE의 REMOVE 옵션을 적용하면 해당 Entity 객체를 삭제 했을 때 연관된 Entity 객체들을 자동으로 삭제할 수 있었습니다.
- 하지만 REMOVE 옵션 같은 경우 연관된 Entity와 관계를 제거했다고 해서 자동으로 해당 Entity가 삭제 되지는 않습니다.
테스트를 위한 데이터 넣기.
@SpringBootTest
public class OrphanTest {
@Autowired
UserRepository userRepository;
@Autowired
FoodRepository foodRepository;
@Test
@Transactional
@Rollback(value = false)
void init() {
List<User> userList = new ArrayList<>();
User user1 = new User();
user1.setName("Robbie");
userList.add(user1);
User user2 = new User();
user2.setName("Robbert");
userList.add(user2);
userRepository.saveAll(userList);
List<Food> foodList = new ArrayList<>();
Food food1 = new Food();
food1.setName("고구마 피자");
food1.setPrice(30000);
food1.setUser(user1); // 외래 키(연관 관계) 설정
foodList.add(food1);
Food food2 = new Food();
food2.setName("아보카도 피자");
food2.setPrice(50000);
food2.setUser(user1); // 외래 키(연관 관계) 설정
foodList.add(food2);
Food food3 = new Food();
food3.setName("후라이드 치킨");
food3.setPrice(15000);
food3.setUser(user1); // 외래 키(연관 관계) 설정
foodList.add(food3);
Food food4 = new Food();
food4.setName("양념 치킨");
food4.setPrice(20000);
food4.setUser(user2); // 외래 키(연관 관계) 설정
foodList.add(food4);
Food food5 = new Food();
food5.setName("고구마 피자");
food5.setPrice(30000);
food5.setUser(user2); // 외래 키(연관 관계) 설정
foodList.add(food5);
foodRepository.saveAll(foodList);
}
@Test
@Transactional
@Rollback(value = false)
@DisplayName("연관관계 제거")
void test1() {
// 고객 Robbie 를 조회합니다.
User user = userRepository.findByName("Robbie");
System.out.println("user.getName() = " + user.getName());
Food chicken = null;
for (Food food : user.getFoodList()) {
if(food.getName().equals("후라이드 치킨")) {
chicken = food;
}
}
if(chicken != null) {
user.getFoodList().remove(chicken); // 연관된 음식 Entity 제거 : 후라이드 치킨
}
// 연관관계 제거 확인
for (Food food : user.getFoodList()) {
System.out.println("food.getName() = " + food.getName());
}
}
}
1. orphanRemoval 적용하지 않았을 때 테스트 실행
고객 Robbie(user_id = 1)는 고구마 피자, 아보카도 피자, 후라이드 치킨을 가지고 있었습니다.
예상대로 후라이드 치킨을 제외하고 출력했습니다.
하지만 데이터 베이스에서는 삭제되지 않았습니다.
2. orphanRemoval 적용한 후 테스트 실행
@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); // 외래 키 설정
}
}
orphanRemoval 적용 후 delete 쿼리가 실행됩니다.
데이터 베이스에서도 삭제된 것을 확인할 수 있습니다.
정리
`1 : n = 고객 : 음식(fk)`
Cascade = CascadeType.REMOVE 적용 시
1. 특정 고객 삭제 시 음식 데이터도 삭제됩니다.
2. 특정 고객이 갖는 foodList 에서 특정 food 를 골라서 데이터베이스에서 삭제할 수 없습니다.
orphanRemoval = Ture 적용 시
1. 특정 고객 삭제 시 음식 데이터도 삭제됩니다.
2. 특정 고객이 갖는 foodList 에서 특정 food 를 골라서 데이터베이스에서 삭제할 수 있습니다.
'Spring > 팀스파르타' 카테고리의 다른 글
44. Mockito (0) | 2024.12.06 |
---|---|
43. 단위 테스트 (0) | 2024.12.06 |
41. 영속성 전이 (0) | 2024.12.06 |
40. 즉시 로딩, 지연 로딩과 영속성 컨텍스트 (0) | 2024.12.06 |
39. Entity 연관관계 - N 대 M (0) | 2024.12.06 |