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
相关产品推荐
相关产品推荐

