더티체킹이 동작하지 않는 문제 해결하기

임현규·2023년 5월 30일
0

Meca project 개발 일지

목록 보기
20/27
post-thumbnail

발생한 문제

회원 정보 수정을 요청하는 API를 만들었는데 DB에 수정사항이 반영되지 않는 이슈가 있었다.

문제의 코드는 다음과 같다.

	@Transactional
	public MemberDto update(UpdateMemberRequestDto updateMemberRequestDto, Member member) {
		if (updateMemberRequestDto.getName() != null) {
			member.updateName(updateMemberRequestDto.getName());
		}
		if (updateMemberRequestDto.getProfile() != null) {
			member.updateProfile(updateMemberRequestDto.getProfile());
		}
		return MemberMapper.fromEntityToDto(member);
	}

null을 체크하고 null 아니면 해당 속성을 업데이트한다. 이때 save 요청을 하지 않은 이유는 인자로 가져온 엔티티가 영속화 상태일 것이라 생각하고 자동으로 더티 체킹을 수행하리라 생각했기 때문이다.

위와 같이 Member 엔티티를 인자로 받은 이유는

	@PutMapping("/me")
	@Secured("ROLE_USER")
	public ResponseEntity<MemberDto> updateMyProfile(@AuthenticationPrincipal Member member,
		@RequestBody UpdateMemberRequestDto updateMemberRequestDto) {
		MemberDto myProfile = memberService.update(updateMemberRequestDto, member);
		return ResponseEntity.ok(myProfile);
	}

@AuthenticationPrincipal을 활용해 SecurityContext에 있는 회원 정보를 뺴올 수 있었기 때문이다. SecurityContext에 Member 엔티티가 있는 이유는 jwt token 검증 filter 에서 인증에 성공하면 db에서 엔티티를 가져온다.

	@Transactional(readOnly = true)
	public Member findMember(Id memberId) {
		return memberRepository.findById(memberId)
			.orElseThrow(() -> new IllegalArgumentException("회원을 찾을 수 없습니다"));
	}

즉, 회원 수정 요청은 2개의 트랜잭션으로 동작한다.

엔티티 매니저는 서로 다른 트랜잭션과 공유하지 않는다.

내가 생각했던 문제는 이전 트랜잭션에서 얻어온 Member 엔티티는 db를 통해 가져왔으니 영속화 상태이고 다른 트랜잭션에도 해당 객체를 활용하면 엔티티 매니저가 더티 체킹을 해줄줄 알았으나 잘못된 생각이다.

엔티티 매니저의 생명주기는 트랜잭션과 같다. 즉, 하나의 요청에 2개의 트랜잭션이 있다면 엔티티 매니저 또한 2개가 생성되고 소멸된다. 이 과정에서 이 2개의 엔티티 매니저는 서로간의 정보를 공유할 수 없다.

해결

새로운 트랜잭션에서 repository의 save를 호출해 영속화시키면 된다. 그러면 엔티티의 ID는 이미 존재하므로 내부적으로 em.merge(entity)를 호출할 것이다. 그러면 엔티티의 변경 내용이 transaction 커밋시 자동으로 반영이 된다.

참고

트랜잭션에 대해서 잘 설명한 블로그이다.
https://cobbybb.tistory.com/27#TransactionManager%EC%99%80%20EntityManager-1

공부하면서 분석한 트랜잭션
https://velog.io/@e1psycongr00/Spring-Transactional%EA%B3%BC-entityManager-%EA%B4%80%EA%B3%84-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0

profile
엘 프사이 콩그루

0개의 댓글