You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data Couchbase无需修改现有代码如何存储Enum名称而非值

Spring Data Couchbase 枚举存储无侵入调整方案

核心原理:Spring Data Couchbase 默认使用 Jackson 做 JSON 序列化,你遇到的问题是因为 Foo 枚举重写了 toString() 返回自定义 value,序列化时默认调用了该方法。通过调整 Jackson 序列化规则即可实现存储枚举 name() 值,完全不需要修改现有业务代码,同时支持 Map 键场景的枚举处理。

方案一:全局注册自定义枚举序列化模块(最简便,无需修改现有配置)

直接新增一个 Jackson 模块 Bean,Spring Boot 会自动将该模块注入到包括 Couchbase 在内的所有使用的 ObjectMapper 中:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class FooEnumSerializationConfig {

    @Bean
    public SimpleModule customFooEnumModule() {
        SimpleModule module = new SimpleModule("FooEnumSerialization");
        // 枚举值序列化
        module.addSerializer(Foo.class, new StdSerializer<Foo>(Foo.class) {
            @Override
            public void serialize(Foo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                gen.writeString(value.name());
            }
        });
        // 枚举作为Map键的序列化
        module.addKeySerializer(Foo.class, new StdSerializer<Foo>(Foo.class) {
            @Override
            public void serialize(Foo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                gen.writeFieldName(value.name());
            }
        });
        // 枚举值反序列化
        module.addDeserializer(Foo.class, new StdDeserializer<Foo>(Foo.class) {
            @Override
            public Foo deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                return Foo.valueOf(p.getText());
            }
        });
        // 枚举作为Map键的反序列化
        module.addKeyDeserializer(Foo.class, new com.fasterxml.jackson.databind.KeyDeserializer() {
            @Override
            public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
                return Foo.valueOf(key);
            }
        });
        return module;
    }
}

方案二:Couchbase 转换器单独配置

如果项目中 Couchbase 使用独立的 ObjectMapper,不继承全局配置,可以在 Couchbase 配置类中单独调整:

import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;

@Configuration
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

    // 原有Couchbase配置(连接信息、桶配置等)保持不变

    @Override
    public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
        MappingCouchbaseConverter converter = super.mappingCouchbaseConverter();
        // 注册上面定义的customFooEnumModule模块
        converter.getObjectMapper().registerModule(new FooEnumSerializationConfig().customFooEnumModule());
        // 也可以全局开启枚举用name序列化,不需要单独定义序列化器:
        // converter.getObjectMapper().configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, false);
        // converter.getObjectMapper().configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, false);
        return converter;
    }
}

验证

配置完成后,Couchbase 中存储的 Universe 下的 bar 字段的键会直接存储 Moon、Star、Sun 枚举名称,不会再存 Night、Day 等自定义value,读取时也能自动反序列化为 Foo 枚举,完全兼容现有业务逻辑。

内容的提问来源于stack exchange,提问作者Priya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:15:06