JPA - 고아 Entity 삭제
2024. 8. 29. 09:45ㆍJPA
2024/08/29
※ 고아 Entity에 대해 알아보자.
▶ OrphanRemoval
📌 고아 객체(Orphan) 제거란?
JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공하는데 이것을 고아 객체 제거 라 한다. 이 기능을 사용해서 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티가 자동으로 삭제된다.
● CASCADE의 REMOVE 옵션을 적용하면 해당 Entity 객체를 삭제 했을 때 연관된 Entity 객체들을 자동으로 삭제할 수 있었다.
○ 하지만 REMOVE 옵션 같은 경우 연관된 Entity와 관계를 제거했다고 해서 자동으로 해당 Entity가 삭제 되지는 않는다.
➡️ OrphanTest
@Test
@Transactional
@Rollback(value = false)
@DisplayName("연관관계 제거")
void test1() {
// 고객 Robbie 를 조회합니다.
User user = userRepository.findByName("Robbie");
System.out.println("user.getName() = " + user.getName());
// 연관된 음식 Entity 제거 : 후라이드 치킨
Food chicken = null;
for (Food food : user.getFoodList()) {
if(food.getName().equals("후라이드 치킨")) {
chicken = food;
}
}
if(chicken != null) {
user.getFoodList().remove(chicken);
}
// 연관관계 제거 확인
for (Food food : user.getFoodList()) {
System.out.println("food.getName() = " + food.getName());
}
}
● 후라이드 치킨 Entity 객체와 연관관계를 제거했지만 Delete SQL이 수행되지 않는 것을 확인할 수 있다.
✅ JPA에서는 이를 간편하게 처리할 수 있는 방법으로 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 SQL이 수행되어 후라이드 치킨 데이터가 삭제된 것을 확인할 수 있다.
● 추가로 orphanRemoval 옵션도 REMOVE 옵션과 마찬가지로 해당 Entity 즉, Robbie Entity 객체를 삭제하면 연관된 음식 Entity들이 자동으로 삭제된다.
⚠️ 고아 객체 제거 사용 시 주의사항❗
👉 orphanRemoval이나 REMOVE 옵션을 사용할 때 삭제하려고 하는 연관된 Entity를 다른 곳에서 참조하고 있는지 아닌지를 꼭 확인해야한다.
● A와 B에 참조되고 있던 C를 B를 삭제하면서 같이 삭제하게 되면 A는 참조하고 있던 C가 사라졌기 때문에 문제가 발생할 수 있다.
● 따라서 orphanRemoval 같은 경우 @ManyToOne 같은 애너테이션에서는 사용할 수 없다.
✅ @ManyToOne이 설정된 Entity는 해당 Entity 객체를 참조하는 다른 Entity 객체들이 있을 수 있기 때문에 속성으로 orphanRemoval를 가지고 있지 않다.
'JPA' 카테고리의 다른 글
스프링 - JPA 지연로딩 (1) | 2024.08.27 |
---|