게시글을 삭제 한다면, 해당 게시글에 소속된 댓글은 함께 삭제된다.
[Post Entity 中 ...]
Post 객체가 삭제 될때, 해당 Comment 도 삭제 된다.
일반적인 다른 게시판 서비스에서 회원이 탈퇴할 경우, 해당 회원이 작성한 게시글 / 댓글이 함께 삭제 되기도 한다.
'에브리타임' 과 같은 서비스는 회원이 탈퇴하더라도 게시글 / 댓글이 함께 삭제 되지 않고, 작성자 명이 '알수없음' 으로 변경된다.
회원 탈퇴를 할 경우, 게시글 / 댓글 의 작성자를 'unknown' 으로 변경하는 기능을 구현할 것이다.
회원 탈퇴 시, 게시글 / 댓글의 작성자를 '탈퇴 회원' 에서 'unknown' 회원으로 변경하는 방식으로 할 것이다.
1. PostRepository
public interface PostRepository extends JpaRepository<Post, Long> {
//작성자 : member -> unknown
@Modifying
@Query("update Post p set p.member = :unknownMember where p.member.id = :memberId")
void updateMemberToUnknownByMemberId(@Param("memberId") Long memberId,
@Param("unknownMember") Member unknownMember);
}
memberId : 탈퇴 회원 ID
unknownMember : 'unknown' 회원
작성자를 '탈퇴 회원' -> 'unknown 회원' 으로 변경한다.
2. CommentRepository
public interface CommentRepository extends JpaRepository<Comment, Long> {
//작성자 : member -> unknown
@Modifying
@Query("update Comment c set c.member = :unknownMember where c.member.id = :memberId")
void updateMemberToUnknownByMemberId(@Param("memberId") Long memberId,
@Param("unknownMember") Member unknownMember);
}
memberId : 탈퇴 회원 ID
unknownMember : 'unknown' 회원
작성자를 '탈퇴 회원' -> 'unknown 회원' 으로 변경한다.
3. PostService
//PostService.class 中...
/**
* 회원 삭제 시, 작성한 Post 의 작성자를 unknown 으로 변경
*/
// 작성자 -> unknown 객체
@Transactional
public void updatePostMemberToUnknown(Long memberId) {
Member unknownMember = memberRepository.findByUsername("unknown").get();
postRepository.updateMemberToUnknownByMemberId(memberId, unknownMember);
}
Post의 작성자를 'unknown' 으로 변경한다.
4. CommentService
//CommentService.class 中...
/**
* 회원 삭제 시, 작성한 Comment 의 작성자를 unknown 으로 변경
*/
// 작성자 -> unknown 객체
@Transactional
public void updateCommentMemberToUnknown(Long memberId) {
Member unknownMember = memberRepository.findByUsername("unknown").get();
commentRepository.updateMemberToUnknownByMemberId(memberId, unknownMember);
}
Post의 작성자를 'unknown' 으로 변경한다.
5. MemberService
//MemberService.class 中...
/**
* 회원 삭제
* @param memberId : 삭제 회원 ID
* @return : 삭제 회원 ID
*/
@Transactional
public Long deleteMember(Long memberId) {
//1. 삭제 대상 찾기
Optional<Member> findMember = memberRepository.findById(memberId);
//*예외처리 : 존재하는 회원인가?
if (!findMember.isPresent()) {
throw new DataNotFoundException("존재하지 않는 회원 입니다.");
}
Member member = findMember.get(); //삭제 대상
String loggedName = SecurityContextHolder.getContext().getAuthentication().getName(); //로그인된 username
//*예외처리 : '삭제 회원'과 '로그인 회원'이 동일한가?
if (!member.getUsername().equals(loggedName)) {
throw new UnauthorizedAccessException("접근 권한이 없습니다.");
}
//2-1. 해당 회원의 작성한 post 의 작성자를 'unknown' 으로 변경
postService.updatePostMemberToUnknown(memberId);
//2-2. 해당 회원이 작성한 comment 의 작성자를 'unknown' 으로 변경
commentService.updateCommentMemberToUnknown(memberId);
//3. 회원 삭제
memberRepository.delete(member);
return memberId;
}
memberRepository.delete 직전에, 게시글 / 댓글의 작성자를 unknown 으로 변경한다.
6. MemberApiController
//MemberApiController.class 中...
/**
* 회원 삭제 API
*
* @param memberId : 삭제 회원 ID
* @return : 삭제 회원 ID
*/
@DeleteMapping("/{memberId}")
public ResponseEntity<?> deleteMember(@PathVariable Long memberId,
HttpServletRequest request, HttpServletResponse response) {
//1. 회원 삭제
Long deleteMemberId = memberService.deleteMember(memberId);
//2. 로그아웃 처리
logoutUser(request, response);
return ResponseEntity.ok("회원" + deleteMemberId + "이(가) 탈퇴 되었습니다.");
}
// 회원 로그아웃 (세션 정리를 통한)
private void logoutUser(HttpServletRequest request, HttpServletResponse response) {
new SecurityContextLogoutHandler().logout(request, response, null);
SecurityContextHolder.clearContext(); //세션을 정리
}
완성 화면
Member77을 탈퇴하자, 작성한 게시글/댓글 의 작성자가 'unknown' 으로 변경 된 것을 확인 할 수 있다.