1. 문제 상황
배달 앱을 만드는 팀프로젝트 중 요구사항으로
모든 테이블에 생성한 사람, 생성날짜, 업데이트한 사람, 업데이트날짜를 기록하라는 것이 있었다.
이것을 구현하기 위해 JpaAuditing, AuditorAware를 활용하여 통해,
해당 테이블에 변경사항이 있을 시 현재 로그인 중인 사용자의 id를 자동으로 기록되도록 구현하려고 했다.
참고한 자료는 아래 블로그 글이다.
https://javacpro.tistory.com/85
[Spring Boot] JPA, AuditorAware 사용하여 사용자정보 자동 입력
1. Config 생성 @EnableJpaAuditing 어노테이션을 추가하여 Annotation 을 사용하여 Audit 활성화 @Configuration @EnableJpaAuditing public class JpaAuditConfig { @Bean public AuditorAware auditorProvider() { return new AuditorAwareImpl(); } }
javacpro.tistory.com
문제는 AuditorAware 기능을 추가한 후,
원래는 잘 되던 결제 요청 API가 먹히지 않는 것이었다.
2. 원인 파악
참고한 블로그 글에서는 createdBy 와 updatedBy 가 Long 타입으로 선언되어 있었다.
userId가 들어가기 때문에 Long 타입으로 선언한 것 같고
userId가 데이터베이스에서 자동으로 채번이 되는 값,
MySQL로 예를 들면 Auto Increment 로 만들어지는 값으로 판단된다.
우리 팀 프로젝트도 MySQL은 아니지만, 동일하게 데이터베이스에서 자동으로 채번해주는 값,
Long 타입이 들어가기 때문에 동일하게 구현해줬던 것이다.
하지만, 우리 팀의 BaseEntity를 확인해보니 createdBy 와 updatedBy가 String으로 선언되어 있었다.
// 블로그의 BaseEntity
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public abstract class BaseEntity {
...
//등록자
@CreatedBy
@Column(updatable = false)
protected Long createBy;
//수정자
@LastModifiedBy
protected Long lastModifedBy;
}
출처: https://javacpro.tistory.com/85 [버물리의 IT공부:티스토리]
// 우리 팀의 BaseEntity
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public abstract class BaseEntity {
...
//등록자
@CreatedBy
@Column(updatable = false)
protected String createBy;
//수정자
@LastModifiedBy
protected String lastModifedBy;
}
따라서, 결제 요청 API를 호출했을 때, 결제 테이블에 데이터가 남는 순간 createdBy 와 updatedBy가 자동으로 기록되어야 하는데 Long -> String 타입 변환이 안되니, API가 실패가 나는 것이었다.
3. 해결 방법
블로그에서는 AuditorAware<Long> 으로 제네릭을 Long으로 잡아주고 있으므로,
우리는 우리 팀 프로젝트에 맞게 AuditorAware<String> 으로 제네릭을 잡아주면, 간단히 해결될 것이다.
// 참고한 블로그 코드
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
public class AuditorAwareImpl implements AuditorAware<Long> {
@Override
public Optional<Long> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(null == authentication || !authentication.isAuthenticated()) {
return null;
}
//사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
CustomUserDetails userDetails = (CustomUserDetails)authentication.getPrincipal();
return Optional.of(userDetails.getId());
}
}
출처: https://javacpro.tistory.com/85 [버물리의 IT공부:티스토리]
// 우리 팀 프로젝트에 적용한 코드
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Optional;
public class AuditorAwareImpl implements AuditorAware<String> {
...
}
4. 결과
created_by 와 updated_by가 정확하게 요청한 userId가 들어가고 있음을 확인할 수 있었다.
'자바 심화 2기' 카테고리의 다른 글
CodeBloom - AI를 활용한 주문 관리 플랫폼 프로젝트 결과물 (1) | 2024.11.19 |
---|---|
2024 11 14 TIL - Spring Data의 @PageableDefault, @SortDefault (0) | 2024.11.14 |
2024 11 13 TIL - QueryDSL, BooleanExpression (1) | 2024.11.13 |
2024 11 12 TIL - 회원가입하려는데 왜 자꾸 인증하라고 그러는걸까? (Feat. AuditorAware) (0) | 2024.11.12 |
[Spring 심화 2기] 9팀 코드블룸 - CH.1 AI 검증 비즈니스 프로젝트 S.A (0) | 2024.11.07 |