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

Micronaut集成Postgres JSONB字段遇类型转换问题求助

解决Micronaut + Postgres JSONB字段映射问题

针对你遇到的Postgres JSONB字段无法正确映射的问题,给出以下可行解决方案:

方案1:修正自定义转换器的目标类型

你之前的转换器将List<Metadata>转为String,但Postgres的JSONB字段需要原生JSON类型而非字符串,导致类型不匹配报错。调整转换器直接生成Postgres的PGobject对象即可解决:

修改后的JsonbConverter代码

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.inject.Singleton;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import lombok.RequiredArgsConstructor;
import org.postgresql.util.PGobject;

import java.io.IOException;
import java.util.List;

@Singleton
@RequiredArgsConstructor
@Converter(autoApply = true)
public class JsonbConverter implements AttributeConverter<List<Metadata>, PGobject> {

    private final ObjectMapper objectMapper;

    @Override
    public PGobject convertToDatabaseColumn(List<Metadata> attribute) {
        PGobject pgObject = new PGobject();
        pgObject.setType("jsonb");
        try {
            pgObject.setValue(attribute == null ? null : objectMapper.writeValueAsString(attribute));
            return pgObject;
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error converting to JSONB", e);
        }
    }

    @Override
    public List<Metadata> convertToEntityAttribute(PGobject dbData) {
        try {
            return dbData == null ? null : objectMapper.readValue(dbData.getValue(),
                objectMapper.getTypeFactory().constructCollectionType(List.class, Metadata.class));
        } catch (IOException e) {
            throw new RuntimeException("Error parsing JSONB", e);
        }
    }
}

实体类字段注解调整

@Value
@Embeddable
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) // 关键:添加JPA所需的无参构造函数
class StoredIndexingDetails {

    @Nullable
    @Convert(converter = JsonbConverter.class)
    @Column(name = "indexing_primary_metadata", columnDefinition = "jsonb")
    List<Metadata> primaryMetadata;
}

方案2:使用Hibernate Types简化映射(无需自定义转换器)

如果不想手动编写转换器,可以引入第三方库hibernate-types自动处理JSONB映射:

添加依赖(Gradle示例)

implementation 'com.vladmihalcea:hibernate-types-60:2.21.1'

实体类字段配置

@Value
@Embeddable
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
class StoredIndexingDetails {

    @Nullable
    @Type(type = "jsonb")
    @Column(name = "indexing_primary_metadata", columnDefinition = "jsonb")
    List<Metadata> primaryMetadata;
}

关键问题说明

你之前添加@ColumnTransformer后字段为空的核心原因是:

  • @Embeddable类必须提供无参构造函数才能被JPA正确实例化并赋值
  • @Value注解默认只生成全参构造函数,添加@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)可在保留@Value特性的同时满足JPA要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:25:13