오늘의 문제점
오늘도 AI한테 신나게 물어본다.
'퀘스퀘이드를 할려면 어떻게 하나요?'
'아하! 사용자님! 그건 그냥 간단하게 JPA로 해결하시면 돼요!'
@OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY)
@ToString.Exclude // Lombok @ToString 사용 시 순환 참조 방지
private List<Product> products = new ArrayList<>();

'아니 이렇게 쉽다고? 진짜 JPA는 신의 기술인가?'
라고 생각하던 중.. 문제가 생긴다.
계속 FOREIGN KEY 제약 문제로 안됐다!
'아니 AI야? 이렇게 하면 된다고 말했잖아'
그랬더니 ai 왈,
'ㅎㅎ 유저님 그러시지 말고, 서비스단에서 직접 삭제하시는 쿼리문을 날리세요!'
그럼 그렇지.. 그냥 쉽게 날로먹을수 있는게 아니었다.
그렇게 코드 수정을 하는데..
@Override
@Transactional
public void deleteUser(Long uid) {
Users user = usersRepository.findUserByUid(uid);
if (user != null) {
cartRepository.deleteByUserUid(uid); //순서 중요
productRepository.deleteByUserUid(uid);
usersRepository.delete(user);
}
}

'안된다'
안된다.. 또 비슷한 오류가 나면서 안된다..
우리의 장바구니 테이블은, 두가지의 FOREIGN KEY 제약을 갖고 있었는데
uid만 참조하는것이 아니라, prod_id, 상품 id도 갖고 있던것이다.
cart 삭제 - prod 삭제 - user 삭제를 하는 도중,
'다른 사람' 이 장바구니에 넣어둔 prod를 삭제할려는데, 다른사람의 장바구니에서는 내 상품이 남아있던것!
유저를 삭제하기 위해서는, 유저에 연결된 상품을 먼저 삭제해야하지만,
상품을 삭제하기 위해서는, 상품에 연결된 장바구니를 먼저 삭제했어야 하는것이다!
해결 코드
if (user != null) {
//단순무식 코드, uid-product-cart로 참조해서 그냥 카트를 다 부수고 시작한다!
List<Product> products = productRepository.findProductsByUserUid(uid);
for (Product product : products) {
List<Cart> carts = cartRepository.findCartsByProduct(product);
cartRepository.deleteAll(carts);
}
cartRepository.deleteByUserUid(uid); //순서 중요
productRepository.deleteByUserUid(uid);
usersRepository.delete(user);
}
두구두구두구두구.. 결과는?

성공했다!
분명 이 코드를 갖다주면 AI도 날 칭찬해주겠지?
라고 생각하며 보내줬더니..
'ㅎㅎ; 유저님 혹시 N+1 문제라고 아세요? 이러면 성능 박살나요~'

알고 있었다..
코드를 쓰면서도
'어라? 이거 시간 복잡도 폭발하는 느낌이 드는데..'
라는 생각이 들고 있었는데..
다음 시간에는 N+1 문제 해결로 돌아오도록 하겠다..