• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

JPA 연관관계 질문입니다.

22.09.15 09:28 작성 조회수 532

1

안녕하세요!

강의는 다 들었는데 JPA 공부를 하다가 궁금한점이 있어서

질문을 남겨봅니다.

현재 User 와 UserLoanHistory 는 1:N 관계이고,

User쪽에 cascade 옵션이 걸려 있는데요.

그러면 User 가 삭제되면 UserLoanHistory 가 삭제될 때

User 와 연관관계가 있는 히스토리의 개수만큼 delete 쿼리가 나갈거 같은데요. 뭔가 비효율적인거 같다는 생각이 들어서 찾아보니 1:N 에서 N 쪽에 @OnDelete(action = OnDeleteAction.CASCADE)

옵션을 주어서 디비단에서 해결하는 방법이 있는거 같긴한데 이걸 쓰는게 맞을지 고민이 되서 질문드립니다.

이 옵션은 왠지 위험해 보이는데... 그럼 cascade 옵션을 안쓰고 respository 에서 deleteAllInBatch 로 N 쪽을 지우고 1을 따로 지우는게 나을지...

질문을 정리해보자면

  • 1:N 관계에서 1을 삭제시 delete 쿼리가 N개 만큼 나가서 비효율적일거 같음

  • N쪽에 @OnDelete 옵션을 줘서 디비에 외래키 cascade delete 옵션을 주는게 나을지?

  • 수동으로 N쪽을 삭제하고 1 을 삭제하는게 나을지?

 

어떤쪽이 더 좋은 선택인지 고민인데 좋은 의견 주시면 감사하겠습니다.

답변 1

답변을 작성해보세요.

1

안녕하세요! opensesame 님~!!! 크으~ 매우 좋은 질문이십니다! 😊

넵넵, 말씀해주신것처럼 cascade 옵션이 전체로 걸려 있으면 delete가 될 때 (정확히는 JPA EntityManager의 remove가 호출 될 때) N쪽 Entity로 remove가 전파되면서 delete 쿼리가 N번 발생하게 됩니다! 때문에 1 : N 연관관계를 만들 때는 데이터 양에 따라 적절한 방법론을 취해야 하지요!

 

프로그래밍에 정해진 정답은 없고, 저의 개인적인 생각이지만 질문 주신 내용에 답변을 드려보자면

 

[N 쪽에 @OnDelete 옵션을 주는 방식이 나을지?]

이 옵션은 제가 사용해보지 않아서 찾아보니 FK를 이용한 DB의 옵션인 것 같았습니다! 동작하는 느낌이 DB의 트리거와 비슷한 것 같은데요~ 저는 객체끼리 연관관계를 맺더라도 DB Table에서는 FK 자체를 사용하지않기도 하고, Trigger, Stored Procedure와 같이 DB의 기능을 지양하는 편이라 아무래도 꺼려지는 것 같습니다!

아마 opensesame님께서도 비슷한 느낌을 "왠지 위험해 보이는데.."라고 표현해주신 것 같아요~ ㅎㅎㅎㅎ

 

[수동으로 N쪽을 삭제하고 1 을 삭제하는게 나을지?]

위의 옵션이 애매하다면, 당연히 이 방법을 사용해야 합니다! 말씀해주신 deleteAllInBatch 는 특정 column을 기준으로 삭제하는게 아니라 연관관계를 무시한채 해당 테이블 전체를 지우는 것이다 보니, 사용하기는 어려울 것 같고요, 저라면 Querydsl에서 delete 쿼리를 적절하게 짤 것 같습니다!! 물론 여기서도 고민해볼 거리는 있습니다!

예를 들어... 1) 1과 N을 같이 삭제하는 것에 대한 문제가 존재할 수 있는지 - 예를 들면 N 쪽의 데이터가 너무 많아 1은 0.01초만에 삭제되고 N은 0.1초만에 삭제된다면 1부터 삭제 시켜서 API에는 OK를 내려주고, N 쪽은 비동기적으로 처리할 수도 있겠죠! 2) 1과 N을 비동기적으로 삭제해도 괜찮은지, 비동기적으로 삭제할 거라면 어떤 방법론을 사용할 것인지 와 같은 고민거리입니다 ㅎㅎㅎㅎ

 

또한, 근본적으로 1 : N 관계에서 N 쪽에 데이터가 꽤 많다면 JPA 연관관계를 꼭 맺어야 하는가도 고민을 해보아야 합니다. 같은 애그리거트라 하더라도, 성능적인 이유로 객체간의 연관관계를 반드시 맺어야 할 필요는 없으니까요..!!

이러한 기술적인 Trade-Off 외에, resource 적인 Trade-Off도 생각해볼 수 있습니다!

사실 1 + N 에서 N이 20~30개 수준이라면 크게 문제되지는 않아요!! 쓰기지연으로 인해 Network I/O를 최소화 할 수도 있고요! 물론 줄이면 좋긴하죠 ㅎㅎㅎㅎ 하지만 이렇게 줄이기 위해 추가적인 resource가 얼마나 들어갈지, 그 resource 대비 가치가 얼마나 있을지도 고민해볼 포인트입니다!!

 

아이고~ 제가 살짝 삼천포로 빠졌군요 ㅎㅎㅎㅎㅎ 결론은 저라면, 후자의 방법을 선택할 것 같습니다! 😊

좋은 질문 주셔서 감사드립니다~~ 편안한 밤 되세요~!! 🙇

 

 

 

 

opensesame님의 프로필

opensesame

질문자

2022.09.15

항상 좋은 답변 해주셔서 감사합니다.

덕분에 많이 배우고 있습니다.

편안한 밤 되세요!!! 🌕