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类型作为实体字段
这种方式最直接,无需额外转换器:
- 修改实体类,注册
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; }
- 将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>,可以定义转换器实现类型映射:
- 创建转换器类:
@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()); } }
- 修改实体类,应用转换器并配置类型:
@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; }
- 直接使用
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
相关产品推荐
相关产品推荐

