Kotlin Json 역직렬화시 생성자 에러

hanana·2024년 2월 4일
0
post-custom-banner
Error occurs while validation org.springframework.data.redis.serializer.SerializationException:
Could not read JSON: Cannot construct instance

redis를 통해서 로그인시 사용자 정보를 캐싱하고
이후 요청에 대해서 사용자 검증을 캐시데이터를 조회하는식으로 구조를 잡았었다.
의도와는 다르게 정상적으로 데이터가 있고, 생성자도 있었음에도 문제가 발생하고 있었다.

다음은 내 UserDto 코드이다.

@JsonIgnoreProperties(ignoreUnknown = true)
data class User (
    val userName: String,
    val _password: String,
    val userRole: UserRole? = null,
    @JsonIgnore
    var registeredAt: LocalDateTime? = null,
    @JsonIgnore
    var updatedAt: LocalDateTime? = null,
    @JsonIgnore
    var deletedAt: LocalDateTime? = null,
    var id: Long? = null,
    ) : UserDetails{

    constructor(entity: UserEntity): this(
            entity.userName,
            entity.password,
            entity.role,
            entity.registeredAt,
            entity.updatedAt,
            entity.deletedAt,
            entity.id,
        )


    companion object {
        fun fixture(
            userName: String ="userName",
            password: String ="password",
            userRole: UserRole? = null,
            registeredAt: LocalDateTime? = null,
            updatedAt: LocalDateTime? = null,
            deletedAt: LocalDateTime? = null,
            id: Long? = null,

        ) : User {
            return User(
                userName = userName,
                _password = password,
                userRole = userRole,
                registeredAt = registeredAt,
                updatedAt = updatedAt,
                deletedAt = deletedAt,
                id = id,
            )
        }
    }
    fun toEntity(): UserEntity {
        return UserEntity(userName, _password, userRole, registeredAt, updatedAt, deletedAt, id)
    }

    // 스프링 시큐리티 관련 //
}

간단하게 필드가 정의되어 있고,
Entity메소드를 통해 dto를 생성하는 생성자,
fixture메소드를 두어 테스트코드의 편의성
toEntity메소드를 통해 JPA활용시 Entity 객체로 변경해주는 코드였다.


문제는 기본생성자를 못찾기 때문!

코틀린은 보일러코드의 양을 줄여주고,
data class로 선언해두어서 당연히 기본생성자를 제공할 수 있을것이라고 생각한 것이 문제였다.

정확히 파악하려면 내부동작을 더 파악해보아야 겠지만,
객체를 생성하는 과정에서 기본생성자가 없었기 때문이였다.
@NoArgsConstructor 어노테이션이랑은 별개로 데이터를 역직렬화 하는 과정에서
명시적으로 선언된 Entity를 통해 dto를 생성하는 메소드를 사용하는것 처럼 보였다.

따라서 스프링은 '내가 받은건 Json 타입이고 변환을 해야 하는데 왠 UserEntity? 나이거 변환못해!' 라는 듯한 에러를 던져주는 문제였다.

이에따라
기본 생성자를 명시적으로 추가해주었다,

constructor(): this("","") // Json 역직렬화시 사용
constructor(entity: UserEntity): this(
        entity.userName,
        entity.password,
        entity.role,
        entity.registeredAt,
        entity.updatedAt,
        entity.deletedAt,
        entity.id,
)

constructor(): this("","") 코드를 통해서 해당문제를 해결할 수 있었다.

profile
성숙해지려고 노력하지 않으면 성숙하기까지 매우 많은 시간이 걸린다.
post-custom-banner

0개의 댓글