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

Java下将OpenAI Embedding存储至PostgreSQL遇到的问题

解决方案:将OpenAI Embedding存储到PostgreSQL vector列

核心问题分析

你遇到的错误是因为Hibernate默认不识别PostgreSQL的vector类型,之前的转换器把List<Double>转成Double[]后,Hibernate将其视为二进制数组(bytea),与目标列的vector类型不匹配;而jsonb方案无法读取是因为缺少正确的类型映射逻辑。

步骤1:引入pgvector Java依赖

PostgreSQL的vector类型需要专门的客户端库支持,添加以下Maven依赖:

<dependency>
    <groupId>com.github.pgvector</groupId>
    <artifactId>pgvector-java</artifactId>
    <version>0.10.0</version>
</dependency>

步骤2:方案一:直接使用Vector类型作为实体字段

这种方式最直接,无需额外转换器:

  1. 修改实体类,注册vector类型并定义字段:
@Entity
@Data
@Table(name = "explicit_questions")
@EntityListeners(AuditingEntityListener.class)
@TypeDef(name = "vector", typeClass = VectorType.class)
public class ExplicitQuestion implements IBaseModel {
    // 其他字段省略...

    @Type(type = "vector")
    @Column(columnDefinition = "vector(1536)")
    private Vector embedding;
}
  1. 将OpenAI返回的List<Double>转换为Vector对象后存入数据库:
EmbeddingResult embeddingResult = openAIService.createEmbedding(embeddingInput);
List<Double> embeddingsList = embeddingResult.getData().get(0).getEmbedding();
// 转换为pgvector的Vector对象
Vector embedding = new Vector(embeddingsList);
// 设置到实体并保存
explicitQuestion.setEmbedding(embedding);
questionRepository.save(explicitQuestion);

步骤3:方案二:保留List字段,使用自定义转换器

如果你想保持实体字段为List<Double>,可以定义转换器实现类型映射:

  1. 创建转换器类:
@Converter(autoApply = true)
public class ListToVectorConverter implements AttributeConverter<List<Double>, Vector> {
    @Override
    public Vector convertToDatabaseColumn(List<Double> attribute) {
        if (attribute == null || attribute.isEmpty()) {
            return null;
        }
        return new Vector(attribute);
    }

    @Override
    public List<Double> convertToEntityAttribute(Vector dbData) {
        if (dbData == null) {
            return new ArrayList<>();
        }
        return Arrays.asList(dbData.getValues());
    }
}
  1. 修改实体类,应用转换器并配置类型:
@Entity
@Data
@Table(name = "explicit_questions")
@EntityListeners(AuditingEntityListener.class)
@TypeDef(name = "vector", typeClass = VectorType.class)
public class ExplicitQuestion implements IBaseModel {
    // 其他字段省略...

    @Convert(converter = ListToVectorConverter.class)
    @Type(type = "vector")
    @Column(columnDefinition = "vector(1536)")
    private List<Double> embedding;
}
  1. 直接使用List<Double>赋值即可,转换器会自动处理类型转换:
EmbeddingResult embeddingResult = openAIService.createEmbedding(embeddingInput);
List<Double> embeddingsList = embeddingResult.getData().get(0).getEmbedding();
explicitQuestion.setEmbedding(embeddingsList);
questionRepository.save(explicitQuestion);

原生查询适配

如果使用自定义原生SQL,需要传入Vector类型参数:

@Query(value = "UPDATE explicit_questions set embedding = :embedding where id = :id", nativeQuery = true)
void updateEmbedding(@Param("id") Long id, @Param("embedding") Vector embedding);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:25:36