[JPA] Entity가 delete가 안된다!!

YoungHo-Cha·2022년 8월 29일
2

Catch Bug Project

목록 보기
12/12
post-thumbnail

Overview

고용(배치 및 매칭)정보를 취소 기능을 구현하면서 해당 엔티티를 삭제를 하여야 했습니다. delete를 사용했지만 delete에 대한 쿼리가 날아가지 않는 문제가 있었습니다.

이번에는 이 문제를 해결하면서 얻은 고찰을 기록해보겠습니다.

기존 로직

엔티티를 삭제하는 비즈니스 로직부터 살펴보겠습니다.

    public DtoOfCancelByEmployer cancelEmployByEmployer(Long memberId, Long boardId){

        // Member Entity 조회
        Member memberEntity = memberService.getMember(memberId);

        // Board Entity 조회
        Board boardEntity = boardService.getBoardEntity(boardId);

        // Member Entity와 Board Entity를 이용하여 Employ 조회
        Employ employEntity = checkCancelAuthorityByEmployer(memberEntity, boardEntity);

        // Employ 엔티티 삭제
        System.out.println("------------------");
        employRepository.delete(employEntity); // 문제의 로직
        System.out.println("------------------");
 
        return //중략.. dto 응답
    }

다음은 checkCancelAuthorityByEmployer()을 살펴보겠습니다.

public Employ checkCancelAuthorityByEmployer(Member memberEntity, Board boardEntity){
        Employ employEntity = employRepository.findByEmployerAndBoard(memberEntity, boardEntity)
                .orElseThrow(() -> new NoPermissionException("해당 글에 대한 권한이 없습니다."));

        return employEntity;
    }

총 로직을 순서대로 살펴보겠습니다.

  1. 사용자 Id, 게시 글 Id를 포함하여 요청
  2. 두 Id 값으로 각각 사용자, 게시글 엔티티 조회(영속화)
  3. 2가지 엔티티를 통해서 고용정보 엔티티 조회(존재하지 않으면 예외 발생)
  4. 조회된 고용정보 엔티티 삭제

무슨 문제?

먼저 다음 로그를 보겠습니다.

위 사진에서 볼 수 있듯이, "delete" 쿼리가 생성되지 않은 것을 볼 수 있었습니다.

문제는 다음과 같았습니다.

사용자, 게시글 엔티티를 조회한 상태에서 고용정보 엔티티를 삭제하면 다음과 같은 문제가 생깁니다.

고용정보 엔티티를 삭제해버리면 이미 조회한 사용자, 게시글 엔티티 속의 Employ는 존재하지만 해당 고용정보는 삭제되게 됩니다. 이 경우에 POJO 에서 동기화 오류가 생길 수 있기 때문에, 삭제 쿼리를 JPA는 날리지 않습니다.

해결 방안

Board와 Member를 Select를 하지 않는 방안을 선택했습니다.

수정된 로직

EmployService.java 수정

삭제 비즈니스 로직 수정

public DtoOfCancelByEmploy cancelEmployByEmploy(Long memberId, Long employId){
       
        // 고용 정보 엔티티 조회
        Employ employEntity = getEmployEntity(employId);
        
        // 요청자의 id가 고용정보의 id가 같은지 확인
        checkStatus(employEntity, memberId);
        
        // 엔티티 삭제
        employRepository.deleteById(employEntity.getId());
        Board boardEntity = employEntity.getBoard();

        return //중략... 응답 dto
    }

권한 체크 로직 수정

public void checkStatus(Employ employEntity, Long memberId){
        if(employEntity.getEmployee().getId() == memberId || employEntity.getEmployer().getId() == memberId){
            return;
        }
        throw new NoPermissionException("해당 글에 매칭되지 않아 취소할 수 없습니다.");
    }

결과는

쿼리가 생성된 것을 볼 수 있었습니다.

profile
관심많은 영호입니다. 궁금한 거 있으시면 다음 익명 카톡으로 말씀해주시면 가능한 도와드리겠습니다! https://open.kakao.com/o/sE6T84kf

0개의 댓글