You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Data JDBC自定义PGobject转换器后仍向PostgreSQL jsonb列插入varchar的问题求助

Spring Data JDBC自定义PGobject转换器后仍向PostgreSQL jsonb列插入varchar的问题求助

我现在遇到一个Spring Data JDBC的棘手问题:明明已经写了自定义的WritingConverter,把Map转成指定类型为jsonbPGobject,但PostgreSQL还是报错说收到的是character varying类型,没法插入到jsonb列里。具体细节如下:

问题现象

PostgreSQL抛出的错误信息:

2025-10-07T08:42:33.310+05:30 ERROR ... DbActionExecutionException: Failed to execute InsertRoot{entity=Item(id=null, names={en=Book, fr=Livre, de=Buch}), idValueSource=GENERATED}
Caused by: org.postgresql.util.PSQLException: ERROR: column "names" is of type jsonb but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 38
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2734) ~[postgresql-42.7.7.jar:42.7.7]

环境信息

  • Spring Boot: 3.5.6
  • Spring Data JDBC: Boot 3.5.6自带版本
  • Java: 21
  • PostgreSQL JDBC驱动: 42.7.7
  • PostgreSQL: 14/15/16版本均复现相同问题

数据库DDL

CREATE TABLE item (
    id BIGSERIAL PRIMARY KEY,
    names JSONB
);

实体类

@Table
@Data
public class Item {
    @Id
    private Long id;
    @Column("names")
    private Map<String, String> names;
}

尝试的转换器与配置

我先后试了两种配置方式,但都没效果:

尝试1:重写JdbcCustomConversions Bean

@Configuration
public class JdbcConfig extends AbstractJdbcConfiguration {

    @Bean
    @Override
    public JdbcCustomConversions jdbcCustomConversions() {
        ObjectMapper objectMapper = new ObjectMapper();
        return new JdbcCustomConversions(Arrays.asList(
            new MapToJsonConverter(objectMapper),
            new JsonToMapConverter(objectMapper)
        ));
    }
}

@WritingConverter
public class MapToJsonConverter implements Converter<Map<String,String>, PGobject> {
    private final ObjectMapper objectMapper;

    public MapToJsonConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public PGobject convert(Map<String,String> source) {
        try {
            PGobject pg = new PGobject();
            pg.setType("jsonb");
            pg.setValue(objectMapper.writeValueAsString(source));
            return pg;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

@ReadingConverter
public class JsonToMapConverter implements Converter<PGobject, Map<String,String>> {
    private final ObjectMapper objectMapper;

    public JsonToMapConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public Map<String,String> convert(PGobject source) {
        try {
            return source.getValue() == null ? null : objectMapper.readValue(source.getValue(), new TypeReference<Map<String,String>>() {});
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

尝试2:重写userConverters方法

@Configuration
public class JdbcConfig extends AbstractJdbcConfiguration {

    @Override
    protected List<?> userConverters() {
        ObjectMapper objectMapper = new ObjectMapper();
        return Arrays.asList(
            new MapToJsonConverter(objectMapper),
            new JsonToMapConverter(objectMapper)
        );
    }
}

保存数据的代码

Item item = new Item();
item.setNames(Map.of("en","Book","fr","Livre","de","Buch"));
itemRepository.save(item);

预期与实际结果

  • 预期:Spring Data JDBC应该触发我的MapToJsonConverter,把Map转成类型为jsonbPGobject(对应JDBC的Types.OTHER类型),让PostgreSQL正确识别为jsonb类型。
  • 实际:PostgreSQL报错说收到的是character varying类型,看起来我的转换器完全没被调用,而是直接把Map转成普通字符串发送了。

求助

有没有大佬能帮我看看哪里配置错了?或者给一个Spring Data JDBC + PostgreSQL jsonb + 自定义转换器的最小可运行示例?万分感谢!

火山引擎 最新活动