Spring Author Auditing 오류

xlwdn·2022년 11월 29일
0
post-custom-banner

Async Annotation을 사용하여 여러 multipartfile을 s3에 업로드하는 기능을 포함하고 있는 Company Entity 생성 함수를 비동기로 실행하도록 하였습니다.


@Async
override fun companySignup(req: CompanySignupRequest, emailCheckCode: String, companyIntroduction: CompanyIntroductionRequest) {
    if (checkEmail(req.companyContact.email, emailCheckCode)) {

		...   

}

그러나 test하던 중 API 자체는 200이 떴으나, 입력 값이 제대로 들어가지 않음을 확인할 수 있었습니다.

(정확히 서술하자면, Company는 User를 상속받고 있었으며, Inheritance 전략으로 Joined를 사용해 위 API를 통해서 생성된 Company Entity는 User table에 제대로 입력되었으나, Company 테이블에 제대로 데이터가 삽입되지 않았습니다. )

에러가 발생한 곳 로그를 확인해보니, 아래와 같은 메시지를 throw 하고 있었습니다.

2022-10-05 22:23:59.562  INFO 1 --- [  XNIO-1 task-3] o.springdoc.api.AbstractOpenApiResource  : Init duration for springdoc-openapi is: 198 ms
2022-10-05 22:25:01.905 ERROR 1 --- [AsyncExecutor-3] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void ...

java.lang.NullPointerException: Cannot invoke "org.springframework.security.core.Authentication.getCredentials()" because the return value of "org.springframework.security.core.context.SecurityContext.getAuthentication()" is null

문제 원인


CompanyTablel에는 여러 file(companyLogo, businessCertificate)들을 fk로 참조하도록 하였으며, 해당 파일들의 업로드가 끝난 이후 url과 함께 Company를 OneToOne으로 매핑한 결과를 각각 테이블에 저장하도록 하였습니다.

그러나, File이 상속받고 있던 BaseAuthorEntity(작성자, 수정자의 PK가 저장되는 entity)가 저장될 때 Jpa Autiditng하는 과정에서 getCurrentAuditorSecurityContext를 참조하지 못하여 발생한 문제였습니다.

문제 해결


Auditing 시 조회하는 SecurityContext의 값이 존재하지 않을 때의 오류를 처리하는 코드를 작성했습니다.

@Configuration
@EnableJpaAuditing
class AuditorAwareConfiguration: AuditorAware<Long> {

    override fun getCurrentAuditor(): Optional<Long> {
				...
				//수정 전
        return SecurityContextHolder.getContext().authentication.credentials
				=====
				//수정 후
        SecurityContextHolder.getContext().authentication?.credentials?.let {
            if (it == "") return Optional.empty()
            return Optional.of(it.toString().toLong())
        }?: return Optional.empty()
    }

}

throw된 에러는 NPE이기 때문에 kotlin에서 java lib를 사용할 때 nullable 처리만 제대로 해주었다면 발생하지 않았을 문제였기에 부주의함이 컸던 오류였습니다.

post-custom-banner

0개의 댓글