1. 문제 상황
- update API 에서,
- 데이터베이스에는 이름 변경이 정상적으로 반영됨
- 하지만 클라이언트에 반환되는 응답 DTO의 updatedAt 값은 변경 전 값이 계속 보여지는 문제 발생
@Transactional
@Override
public UserResponseDTO updateName(Long id, UserRequestDTO requestDTO) {
User user = userRepository.findById(id)
.orElseThrow(() -> UserExceptionFactory.notFoundById(id));
...
user.setName(requestDTO.getName());
return new UserResponseDTO(user);
}
DB 반영 잘됨
응답의 updatedAt 은 변경되지 않음
2. 원인 분석
왜 updatedAt 값 변경이 안될까?
- JPA는 트랜잭션 종료 시점에 데이터베이스에 변경사항을 반영(flush 및 commit)한다.
- 종료 시점: UserResponseDTO updateName(Long id, UserRequestDTO requestDTO){} 가 종료될 때 !
- 변경 사항 반영 전에 응답을 반환하기 때문에, 응답 데이터의 updatedAt 에는 수정 시간이 반영되지 않음.
* 흐름도
해결 방법 1
flush() + refresh() 호출
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final EntityManager entityManager; // 영속성 컨텍스트 접근
@Transactional
@Override
public UserResponseDTO updateName(Long id, UserRequestDTO requestDTO) {
User user = userRepository.findById(id)
.orElseThrow(() -> UserExceptionFactory.notFoundById(id)); // 유저 체크
...
// 이름 변경
user.setName(requestDTO.getName());
// DB에 즉시 반영하고, 영속성 컨텍스트의 엔티티 갱신
userRepository.flush(); // DB에 SQL 실행
entityManager.refresh(user); // DB로부터 다시 조회하여 updatedAt 포함 동기화
return new UserResponseDTO(user);
}
}
해결 방법 2
DB가 아닌 애플리케이션에서 updatedAt 갱신 처리
- @LastModifiedDate 같은 Spring Data JPA Auditing 기능을 활용해, 애플리케이션 레벨에서 updatedAt 필드를 즉시 갱신하게 한다.
- 트랜잭션이 끝나면서 커밋이 발생할 때 내부적으로 flush가 호출되므로, 별도 flush() 호출 없이도 updatedAt이 반영된다.
- 하지만 !!! 이런 경우에는 flush 고려해야 한다
- 트랜잭션이 아직 커밋되지 않은 상태에서, 변경된 updatedAt 값을 즉시 읽어야 할 때
- 하지만 !!! 이런 경우에는 flush 고려해야 한다
@Transactional
@Override
public UserResponseDTO updateName(Long id, UserRequestDTO requestDTO) {
User user = userRepository.findById(id).orElseThrow(() -> UserExceptionFactory.notFoundById(id)); // 유저 체크
// 이름 변경
user.setName(requestDTO.getName());
// DB 에 변경 사항 즉시 반영
userRepository.flush();
return new UserResponseDTO(user);
}
* @LastModifiedDate 와 DB의 ON UPDATE CURRENT_TIMESTAMP 동시 사용 문제 주의
https://gajicoding.tistory.com/353
@LastModifiedDate 와 DB의 ON UPDATE CURRENT_TIMESTAMP 동시 사용 문제
updatedAt 필드를 자동으로 관리하는 방법 2가지JPA Auditing의 @LastModifiedDate: 엔티티가 변경될 때 JPA가 Java 객체의 필드를 수정DB의 ON UPDATE CURRENT_TIMESTAMP: DB에서 직접 updated_at 값을 자동 변경 이 둘을
gajicoding.tistory.com
'Spring > 문제 해결 (Troubleshooting)' 카테고리의 다른 글
@ControllerAdvice가 Filter 예외를 잡지 못하는 문제 해결 (0) | 2025.06.04 |
---|---|
Spring Security 에러 핸들링 오류 해결, /error 접근 권한 문제 (0) | 2025.05.29 |
@LastModifiedDate 와 DB의 ON UPDATE CURRENT_TIMESTAMP 동시 사용 문제 (1) | 2025.05.23 |
Caused by: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName. (0) | 2025.05.12 |
406 Not Acceptable - responseDTO @Getter 의 중요성 (3) | 2025.05.09 |