[TIL] Spring Boot 4.0에서 Redis 직렬화 설정하기 (Jackson2 -> Jackson3 마이그레이션 )

곽태민·2026년 3월 2일

TIL

목록 보기
76/79

Spring Boot 4.0에서 Redis 직렬화 설정하기: Jackson2 → Jackson3 마이그레이션 삽질기

😮‍💨 시작은 단순한 에러 메시지였다.

Spring Boot 4.0으로 프로젝트를 마이그레이션을 하는데, Redis 설정에서 낯선 에러를 마주쳤다.

Unresolved reference 'DefaultTyping'.

분명히 이전 버전에서 동작이 잘 되었는데, 4.0으로 버전을 올린 후 왜 DefaultTyping 을 찾을 수 없나는 건지..

// 기존 코드 (Spring Boot 3.x)
private fun redisObjectMapper(): ObjectMapper =
	JsonMapper.builder()
    .addModule(KotlinModule.Builder().build())
    .activateDefaultTyping(
    	BasicPolymorphicTypeValidator.builder()
        	.allowIfSubType(Any::class.java)
            .build(),
        ObjectMapper.DefaultTyping.NON_FINAL // ❗️ 에러 발생!
    )
    .build()

🤔 문제의 원인: Jackson 2 -> Jackson 3

Spring Boot 4.0의 가장 큰 변화 중 하나는 Jackson 2에서 Jackson 3로의 전환이다.

패키지 변경

버전패키지
Jackson 2.xcom.fasterxml.jackson
Jackson 3.xtools.jackson

DefaultTyping 위치 변경

Jackson 3에서는 DefaultTyping enum이 ObjectMapper 내부 클래스에서 별도 클래스로 분리가 되었다.

// Jackson 2.x
ObjectMapper.DefaultTyping.NON_FINAL

// Jackson 3.x
import tolls.jackson.databind.DefaultTyping
DefaultTyping.NON_FINAL

🛠️ 첫 번째 시도: DefaultTyping의 import 수정

import를 수정하고 다시 빌드를 해보았다.

import tools.jackson.databind.DefaultTyping
import tools.jackson.databind.ObjectMapper
import tools.jackson.databind.json.JsonMapper

그런데 이번에는 다른 에러가 발생했다.

None of the following candidates is applicable:
constructor<T : Any!>(mapper: ObjectMapper, type: Class<T!>): Jackson2JsonRedisSerializer<T>
constructor<T : Any!>(mapper: ObjectMapper, javaType: JavaType): Jackson2JsonRedisSerializer<T>

Jackson2JsonRedisSerializertools.jackson.databind.ObjectMapper를 받지 않는 것 같았다.


🤔 두 번째 문제: Serializer 호환성

API 문서를 찾아보니

@Deprecated(since="4.0", forRemoval=true)
public class Jackson2JsonRedisSerializer<T>

Jackson2JsonRedisSerializer가 Spring Boot Redis 4.0에서 Deprecated가 되었다.

새로운 Serializer 등장

Spring Data Redis 4.0에서는 Jackson 3 전용 Serializer가 새로 추가되었다.

SerializerJackson 버전상태
Jackson2JsonRedisSerializerJackson 2.x (com.fasterxml.jackson)Deprecated
JacksonJsonRedisSerializerJackson 3.x (tools.jackson)권장

클래스 이름에서 2가 빼진 것이 핵심이다.


🔥 최종 해결: JacksonJsonRedisSerializer 사용

완성된 RedisConfig

package com.example.dotzip.common.config

import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.cache.RedisCacheConfiguration
import org.springframework.data.redis.cache.RedisCacheManager
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.data.redis.serializer.JacksonJsonRedisSerializer
import org.springframework.data.redis.serializer.RedisSerializationContext
import org.springframework.data.redis.serializer.StringRedisSerializer
import tools.jackson.databind.ObjectMapper
import tools.jackson.databind.json.JsonMapper
import tools.jackson.module.kotlin.KotlinModule

@Configuration
@EnableCaching
class RedisConfig {

	@Value("\${spring.data.redis.host}")
	private lateinit var host: String

	@Value("\${spring.data.redis.port}")
	private var port: Int = 6379

	@Bean
	fun redisConnectionFactory(): RedisConnectionFactory {
		return LettuceConnectionFactory(host, port)
	}

	@Bean
	fun redisObjectMapper(): ObjectMapper =
		JsonMapper.builder()
			.addModule(KotlinModule.Builder().build())
			.build()

	@Bean
	fun redisCacheManager(
		connectionFactory: RedisConnectionFactory,
		redisObjectMapper: ObjectMapper
	): RedisCacheManager {
		val serializer = JacksonJsonRedisSerializer(redisObjectMapper, Any::class.java)

		val cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
			.serializeKeysWith(
				RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())
			)
			.serializeValuesWith(
				RedisSerializationContext.SerializationPair.fromSerializer<Any>(serializer)
			)

		return RedisCacheManager.builder(connectionFactory)
			.cacheDefaults(cacheConfig)
			.build()
	}

	@Bean
	fun redisTemplate(
		connectionFactory: RedisConnectionFactory,
		redisObjectMapper: ObjectMapper
	): RedisTemplate<String, Any> {
		val serializer = JacksonJsonRedisSerializer(redisObjectMapper, Any::class.java)

		return RedisTemplate<String, Any>().apply {
			setConnectionFactory(connectionFactory)
			keySerializer = StringRedisSerializer()
			valueSerializer = serializer
			hashKeySerializer = StringRedisSerializer()
			hashValueSerializer = serializer
		}
	}

	@Bean
	fun stringRedisTemplate(connectionFactory: RedisConnectionFactory): StringRedisTemplate {
		return StringRedisTemplate(connectionFactory)
	}
}

📋 마이그레이션 체크리스트

Spring Boot 3.x -> 4.0 Redis 설정 마이그레이션 시 확인해야 할 사항들:

1. Jackson 패키지 변경

// Before (Jackson 2)
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule

// After (Jackson 3)
import tools.jackson.databind.ObjectMapper
import tools.jackson.module.kotlin.KotlinModule

2. DefaultTyping 위치 변경 (필요한 경우)

dependencies {
    implementation("tools.jackson.module:jackson-module-kotlin")
    implementation("org.springframework.boot:spring-boot-starter-data-redis")
}

💡 삽질을 줄이기

1. 공식 마이그레이션 가이드를 먼저 확인해보기.

메이저 버전 업그레이드 시 항상 공식 마이그레이션 가이드를 먼저 읽어보는 습관을 들이기로 한다.

2. API 문서에서 Deprecated 확인

에러가 발생하면 해당 클래스의 API 문서를 확인해보고 Deprecated 여부와 대체 클래스를 확인해 볼 수 있다.


🎯 정리

항목Spring Boot 3.xSpring Boot 4.0
Jackson 버전2.x3.x
패키지com.fasterxml.jacksontools.jackson
Redis SerializerJackson2JsonRedisSerializerJacksonJsonRedisSerializer
DefaultTypingObjectMapper.DefaultTypingtools.jackson.databind.DefaultTyping

Spring Boot 4.0 마이그레이션은 생각보다 많은 변화가 있었다. 특히 Jackson 3 전환은 Redis, REST API, 메시지 직렬화 등 다양한 곳에 영향을 미치니 꼼꼼히 확인하는게 좋을 거 같다.

profile
Node.js 백엔드 개발자입니다!

0개의 댓글