인프런 커뮤니티 질문&답변

966kmj님의 프로필 이미지
966kmj

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

영속성 전이(CASCADE)와 고아 객체

cascadetype.remove와 orpphanRemoval = true

작성

·

145

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
안녕하세요. 제가 강의 복습 겸 혼자 개발을 하다가 궁금한점이 생겨 질문드립니다. cascadetype.remove를 설정하면 부모 엔티티가 삭제되면 자식 엔티티도 삭제되는 것이라고 알고 있습니다. 그래서 cascadetype.remove를 설정하고 부모 객체를 삭제했더니 delete 쿼리가 나가지 않았는데, 여기에 더해 orphanRemoval=True까지 설정해줬더니 delete쿼리가 나가서 부모엔티티와 자식엔티티를 모두 삭제해주었습니다.

제가 잘못알고 있는 것인지 아니면 왜 두 가지 모두를 설정해줘야 delete쿼리가 나가는지 궁금해서 여쭤봅니다.

 

 

@Entity
@RequiredArgsConstructor
@Setter @Getter
public class Restaurant {
    @Id
    @GeneratedValue
    private Long restaurantId;

    @Column(unique = true)
    private String name;

    private mealoralcohol meal_alcohol;

    private URL url;

    private int saturdayopentime;

    private int sundayopentime;

    private int maxNumOfPeople;

    private int averagePrice;

    @OneToMany(mappedBy = "restaurant")
    private List<MenuRestaurant> menuRestaurants = new ArrayList<>();
}

 

@Entity
@RequiredArgsConstructor
@Getter @Setter
public class MenuRestaurant {
    @Id
    @GeneratedValue
    private Long menuRestaurantid;

    private mealtype mealtype;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "restaurantId")
    private Restaurant restaurant;

    public void setRestaurant(Restaurant restaurant){
        this.restaurant = restaurant;
        restaurant.getMenuRestaurants().add(this);
    }

}

 

@Repository
@RequiredArgsConstructor
public class RestaurantRepository {
    private final EntityManager em;

    public void save(Restaurant restaurant){
        em.persist(restaurant);
    }

    public Restaurant findById(Long id){
        return em.find(Restaurant.class,id);
    }

    public void delete(Restaurant restaurant){
        Assert.notNull(restaurant,"Entity must not be null!");
        if (em.contains(restaurant)){
            em.remove(restaurant);
        }
    }

   
}

 

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class RestaurantRepositoryTest {
    @Autowired
    RestaurantRepository rr;
    @Autowired
    EntityManager em;


    @Test
    @Rollback(false)
    public void testJPQL() throws Exception{
        Restaurant res1 = new Restaurant();
        res1.setName("res1");
        res1.setAveragePrice(10000);
        res1.setSaturdayopentime(17);
        res1.setSundayopentime(17);
        res1.setMaxNumOfPeople(29);
        res1.setMeal_alcohol(mealoralcohol.Meal);
        em.persist(res1);

        
        MenuRestaurant menures1 = new MenuRestaurant();
        em.persist(menures1);

        menures1.setRestaurant(res1);
        menures1.setMealtype(mealtype.Korean);

        // heavyres1
        MenuRestaurant menures2 = new MenuRestaurant();
        em.persist(menures2);

        menures2.setRestaurant(res1);
        menures2.setMealtype(mealtype.heavy);

        // japaneseres2
        MenuRestaurant menures3 = new MenuRestaurant();
        em.persist(menures3);

        menures3.setRestaurant(res2);
        menures3.setMealtype(mealtype.Japanese);

      
        rr.delete(res1);


    }


}

 

여기서 rr.delete(res1)을 했을 때, Restaurant 클래스의 orphanRemoval=True 설정을 없애면 delete쿼리가 나가지 않습니다.

답변 1

0

안녕하세요. 966kmj님, 공식 서포터즈 y2gcoder입니다.

제가 정확하게 이해한 것인지는 모르겠으나
레스토랑(Restaurant) : 메뉴(MenuRestaurant) 의 관계가 1:N이고 다대일 양방향 관계로 연결되어 있습니다.

그리고 CascadeType.REMOVE 를 사용해서 레스토랑을 삭제할 때 메뉴들도 같이 삭제하고 싶으신 것 같습니다.

그러면 관계상 레스토랑의 @OneToMany() 옵션에 Cascade 를 설정해주셔야 합니다. 왜냐하면 레스토랑을 삭제할 때 연관관계에 있는 메뉴들도 다 같이 삭제하고 싶은 것이기 때문입니다.

제가 966kmj의 요구사항을 잘못 이해한 것이라면 추가로 질문을 남겨주십쇼!

제가 이해한 요구사항이 맞다면 다시 본 강의를 복습해보시고 다음 링크(클릭)도 함께 참고해보시는 것을 권해드립니다!

 

감사합니다.

966kmj님의 프로필 이미지
966kmj

작성한 질문수

질문하기