Spring & SpringBoot

InvalidDataAccessApiUsageException : detached entity passed to persist

땅콩콩 2024. 6. 28. 17:34

JPA 엔티티가 영속성 컨텍스트에서 분리된 상태에서 persist를 호출해서 영속성 컨텍스트에 저장하려고 하니 발생한 오류다.

memberPostRepository.saveAndFlush 메서드를 사용하여 MemberPost 엔티티를 영속성 컨텍스트에 저장해서 해결했다.

2024-06-28T17:10:50.080+09:00 DEBUG 5097 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.backend.kiri.domain.MemberPost]
2024-06-28T17:10:50.086+09:00 DEBUG 5097 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 500 INTERNAL_SERVER_ERROR

 

- saveAndFlush 메서드 : 엔티티를 유지하면서 그 변경사항을 디비에 즉시 플러시한다. 따라서 엔티티가 영속성 컨텍스트에서 분리되어서 상태 인식을 제대로 못하는 문제를 해결할 수 있다.

 

@Transactionalpublic void joinPost(Long postId, String accessToken) {
    String email = jwtUtil.getUsername(accessToken);
    Member member = memberRepository.findByEmail(email).orElseThrow(() -> new NotFoundMemberException("Not Found Member"));
    Post post = postRepository.findByIdAndIsDeletedFalse(postId).orElseThrow(() -> new NotFoundPostException("Not Found Post"));

    if (post.getNowMember() >= post.getMaxMember()) {
        throw new ChatRoomFullException("인원 초과입니다.");
    }

    MemberPost memberPost = new MemberPost(post, member, false);
    memberPost = memberPostRepository.saveAndFlush(memberPost); // 즉시 플러시

    post.setNowMember(post.getNowMember() + 1);
    postRepository.save(post); // Save the post
}

 

엔티티를 즉시 플러시해서 이 엔티티가 영속성 컨텍스트안에서 트랜잭션이 지속되는 동안 계속 관리되도록 한 것이다.