fix: 비밀번호 변경이 실제로 저장되지 않던 버그 (detached 엔티티)
- change-password가 200을 반환하면서도 DB가 안 바뀌었음 - 원인: requireUser()가 트랜잭션 밖에서 조회한 detached User의 필드를 바꿔 JPA 더티 체킹이 작동하지 않음 (managed 엔티티에만 작동) - 해결: changePassword 트랜잭션 안에서 findById로 재조회 → managed 상태로 UPDATE - 학습 포인트 주석 강화: '더티 체킹이 자동 저장'의 숨은 전제(트랜잭션이 관리하는 엔티티) 검증: 변경 200 → 새 비번 로그인 200 → 옛 비번 401. 틀린 현재비번 401. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ecb1298d93
commit
5e8f96719b
@ -152,14 +152,31 @@ public class AuthService {
|
||||
* 비밀번호 변경·결제·탈퇴처럼 되돌리기 어려운 동작 앞에 한 번 더 세우는 관문이다.
|
||||
*/
|
||||
@Transactional
|
||||
public void changePassword(User user, String currentRawPassword, String newRawPassword) {
|
||||
public void changePassword(User loginUser, String currentRawPassword, String newRawPassword) {
|
||||
// ⚠️ 실제로 났던 버그 — 여기서 배우는 "managed vs detached 엔티티".
|
||||
//
|
||||
// 원래 이 코드는 넘어온 loginUser의 필드를 바로 바꿨다:
|
||||
// loginUser.changePassword(...) // ← 이러면 "성공"인데 DB가 안 바뀐다!
|
||||
//
|
||||
// 왜? loginUser는 requireUser()가 트랜잭션 밖에서 조회한 "분리된(detached)" 객체다.
|
||||
// JPA의 변경 감지(더티 체킹)는 "지금 이 트랜잭션이 관리하는(managed)" 엔티티에만 작동한다.
|
||||
// 분리된 객체의 필드를 바꿔봐야 JPA는 알아채지 못해 UPDATE가 나가지 않는다.
|
||||
//
|
||||
// 해결: 이 트랜잭션 안에서 다시 조회한다. 그러면 managed 상태가 되어 더티 체킹이 작동한다.
|
||||
// (멘토 재설정 resetPasswordByMentor는 findById를 트랜잭션 안에서 불러서 처음부터 정상이었다 —
|
||||
// 그 차이가 이 버그의 힌트였다.)
|
||||
//
|
||||
// 교훈: "더티 체킹이 자동으로 저장해 준다"에는 숨은 전제가 있다 — "지금 트랜잭션이 관리하는 엔티티라면".
|
||||
User user = userRepository.findById(loginUser.getId())
|
||||
.orElseThrow(() -> new ResponseStatusException(
|
||||
HttpStatus.UNAUTHORIZED, "로그인이 필요합니다."));
|
||||
|
||||
if (!passwordEncoder.matches(currentRawPassword, user.getPasswordHash())) {
|
||||
throw new ResponseStatusException(
|
||||
HttpStatus.UNAUTHORIZED, "현재 비밀번호가 올바르지 않습니다.");
|
||||
}
|
||||
user.changePassword(passwordEncoder.encode(newRawPassword));
|
||||
// 학습 포인트: save()를 부르지 않아도 된다. @Transactional 안에서 조회한 엔티티는
|
||||
// JPA가 변경을 감지해(더티 체킹) 트랜잭션 커밋 시점에 자동으로 UPDATE 한다.
|
||||
// 이제 user는 managed 상태라, 커밋 시점에 JPA가 변경을 감지해 UPDATE 한다.
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user