-
Spring DATA JPA 게시물 삭제졸업과제/BackEnd 2023. 2. 16. 13:10
게시물 삭제
게시물 삭제를 구현하기전에는 그냥 Repository 불러서 deleteBy로 삭제하면 되겠다. 간단하겠다!! 라고 생각하고
코드를 뚝딱뚝딱 치기 시작했다!
@PostMapping(value = "/post/delete") // /post/delete/{PostId} public PostDeleteResultDto post_delete(Long PostId) { LOGGER.info("[post_delete] 게시물 삭제 컨트롤러 동작. postId: {}",PostId); Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Object principal = authentication.getPrincipal(); User user = (User)principal; PostDeleteResultDto postDeleteResultDto = postService.post_delete(PostId, user.getUid()); return postDeleteResultDto; }
@Transactional public PostDeleteResultDto post_delete(Long PostId,String Uid) { logger.info("[post_delete] 게시물 삭제 로직 동작. postId:{} userId:{}",PostId,Uid); User user = userRepository.findByUid(Uid).orElse(null); PostDeleteResultDto postDeleteResultDto = new PostDeleteResultDto(); postDeleteResultDto.setPostId(PostId); if(user.getPost()==null||user.getPost().getPostId()!=PostId) { logger.info("[post_delete] 사용자가 게시물이 없거나 사용자가 삭제할수 없는 게시물."); setFailResult(postDeleteResultDto); postDeleteResultDto.setMsg("사용자가 권한이 존재하지 않습니다"); return postDeleteResultDto; } postRepository.deleteBypostId(PostId); userRepository.flush(); if(user.getPost()==null) { setSuccessResult(postDeleteResultDto); }else{ setFailResult(postDeleteResultDto); } return postDeleteResultDto; }
Controller에서는 게시물의 id를 받고 현제 세션 유저의 정보를 받아온뒤 postService의 게시물 삭제로직을 호출했다.
postService에서는 PostRepository.deleteBypostId를 호출해 받아온 PostId와 일치하는 엔티티를 삭제시켜주는 로직이다.
user를 조회한뒤 만약 user가 게시물이 없는대 삭제할려하거나 본인게시물이 아닌데 삭제할려는 경우 삭제할수 없도록
if문을 걸어줘서 오류를 처리해주었다. 이렇게 코드를 완성하고 Swagger에서 게시물 삭제 테스트를 해보았다.
PostId가 4번인 게시물 삭제. Post table User Table PostId가 4번인 게시물이 삭제는 되었지만 4번게시물을 가지고있단 User의 데이터도 함께 삭제가 되었다.
게시물을 삭제했는대 로그아웃되면서 아이디가 날라가버린 상황인것...
뭔가 양방향 연관관계를 맺으면서 설정을 잘못해주었다 싶어 Entity를 한번 보았다.
@OneToOne(mappedBy = "post",fetch = FetchType.LAZY,cascade = CascadeType.ALL) private User user;
Post Entity에서 User와의 연관관계가 cascade = CascadeType.ALL로 설정되있어서 Post테이블의 변경상태가
User Table까지 전달되면서 Post Table을 삭제하면서 User Table이 삭제 되버린것이였다.
그래서 cascade를 지워버리고 다시한번 돌려보았다.
왜 안지워지세요? 아 눈아파 cascade를 지워주고 다시한번 게시물을 생성한뒤 삭제해보았는대 게시물 삭제가 되지 않았다.
로그를 봐도 delete 쿼리가 아예 나가지않고 select 쿼리만 나가는걸로 보여서 이상했다.
갑자기 문득 외래키는 참조할수 없는 값을 가질수 없다는 DB규칙이 떠올라서 post가 삭제될려고 하는대 user 객체가
계속 post의 외래키를 참조하고 있어서 삭제가 안되는거 아닐까라는 생각이 낫다.
@Transactional public PostDeleteResultDto post_delete(Long PostId,String Uid) { logger.info("[post_delete] 게시물 삭제 로직 동작. postId:{} userId:{}",PostId,Uid); User user = userRepository.findByUid(Uid).orElse(null); PostDeleteResultDto postDeleteResultDto = new PostDeleteResultDto(); postDeleteResultDto.setPostId(PostId); if(user.getPost()==null||user.getPost().getPostId()!=PostId) { logger.info("[post_delete] 사용자가 게시물이 없거나 사용자가 삭제할수 없는 게시물."); setFailResult(postDeleteResultDto); postDeleteResultDto.setMsg("사용자가 권한이 존재하지 않습니다"); return postDeleteResultDto; } user.setPost(null); postRepository.deleteBypostId(PostId); userRepository.flush(); if(user.getPost()==null) { setSuccessResult(postDeleteResultDto); }else{ setFailResult(postDeleteResultDto); } return postDeleteResultDto; }
그래서 게시물에 삭제가되고 user가 가지고 있는 post를 null로 세팅해주고 게시물을 삭제한다음
userRepository.flush를 호출해서 user의 변경사항을 감지해 DB에 반영될수 있도록 한번 해보았다.
마췸내.... Uid가 a인 회원으로 게시물삭제를 시도했다. 유저 아이디가 a인 회원으로 게시물삭제를 시도했고 게시물도 정상적으로 삭제가됬고
게시물이 삭제가 되면서 게시물 사진도 함께 삭제되는 Delete 쿼리를 확인할수 있었다.
Cascade에 대해서 좀 자세히 알수 있던 게시물 삭제 로직이였던거 같다.
그냥 강의를 들을때는 연관관계가 맺어지는곳 마다 전부 Cascade를 작성하길래 저렇게 하면되나보다 하고
Post와 User게시물 양쪽 전부다 CascadeTypeALL을 선언해줬는대 이렇게 하면 게시물이 삭제되면 유저정보가 삭제되고
유저가 삭제되면 게시물도 같이 삭제되는 경우가 발생한다. 전자의 경우는 일어나면 안되지만 후자의 경우는 발생해야하는 상황이기 때문에 User Entity에 Post 객체에 CascadeTypeALL을 선언해 주었다.
'졸업과제 > BackEnd' 카테고리의 다른 글
Spring Data JPA를 이용한 게시물 댓글 작성 기능 구현 (0) 2023.02.18 게시물 상세페이지 조회. LazyInitializationException (0) 2023.02.17 Spring Date JPA 게시물 수정 (10) 2023.02.15 2월 첫째주 오류 헤쳐나가기 (0) 2023.02.04 Swagger사용시 JWT 토큰 Header에 담기 (0) 2023.02.01