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("","") 코드를 통해서 해당문제를 해결할 수 있었다.