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

Hibernate反序列化PGvector数据库embedding字段时出现流头无效错误

Hibernate反序列化PGvector数据库embedding字段时出现流头无效错误

看起来你踩了Hibernate和PGvector类型映射的坑——它把数据库里PGvector的文本格式当成Java序列化的字节流来解析,直接炸了😅 我之前也遇到过类似的问题,给你拆解下原因和解决方案:

问题根源

错误里的5B2D302E转成字符串是[-0.,这明显是PGvector在数据库里的文本表示形式(比如[-0.123, 0.456, ...])。但Hibernate的SqlTypes.VECTOR默认处理逻辑和PGvector的自定义类型不兼容,它误以为这个字段存的是Java对象序列化后的字节流,结果拿到文本开头就懵了,直接抛出流头无效的错误。

最快解决方法:用PGvector官方的Java工具类

这是最省心的方案,不用自己写自定义类型,官方已经把映射逻辑搞定了:

1. 先加pgvector-java依赖(如果没加的话)

如果是Maven:

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

Gradle的话:

implementation 'com.github.pgvector:pgvector-java:0.10.0'

这个依赖会自动注册PGvector的JDBC类型处理器,让驱动能正确识别vector类型。

2. 调整实体类的embedding字段

把原来的double[]换成PGvector提供的Vector类,然后用VectorJdbcType来映射:

import com.github.pgvector.Vector;
import org.hibernate.annotations.JdbcType;
import org.hibernate.type.descriptor.jdbc.VectorJdbcType;

@Entity
@Table(name = "vector_store")
public class Document {
    // 其他字段保持不变...

    @JdbcType(VectorJdbcType.class)
    @Column(columnDefinition = "vector(1024)")
    private Vector embedding;

    // 如果你需要对外暴露double数组,可以加个转换方法(可选)
    public double[] getEmbeddingAsDoubleArray() {
        return embedding != null ? embedding.toArray() : new double[0];
    }

    public void setEmbeddingFromDoubleArray(double[] array) {
        this.embedding = new Vector(array);
    }

    // 原来的getter/setter可以保留,或者直接用上面的转换方法
}

这样Hibernate就会用官方的类型处理器来解析PGvector字段,不会再把文本当成序列化流了。

如果你坚持要用double[](不想换Vector类)

那可以写个自定义Hibernate类型,手动把PGvector的文本格式转成double数组:

1. 自定义类型类

import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.java.DoubleArrayJavaType;
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
import com.github.pgvector.Vector;

public class PgVectorDoubleArrayType extends AbstractSingleColumnStandardBasicType<double[]> {
    public static final PgVectorDoubleArrayType INSTANCE = new PgVectorDoubleArrayType();

    public PgVectorDoubleArrayType() {
        super(VarcharJdbcType.INSTANCE, DoubleArrayJavaType.INSTANCE);
    }

    @Override
    public String getName() {
        return "pgvector-double-array";
    }

    @Override
    public double[] fromStringValue(String string) {
        // 把PGvector的文本格式直接转成double数组
        return new Vector(string).toArray();
    }
}

2. 修改实体类注解

把原来的@JdbcTypeCode(SqlTypes.VECTOR)@Array换成自定义类型:

import org.hibernate.annotations.Type;

@Entity
@Table(name = "vector_store")
public class Document {
    // 其他字段不变...

    @Type(PgVectorDoubleArrayType.class)
    @Column(columnDefinition = "vector(1024)")
    private double[] embedding;

    // getters and setters
}

额外排查点

  1. 确认数据库里已经正确安装了pgvector扩展(你能插入数据应该没问题,但还是可以再查下)
  2. 确保PostgreSQL JDBC驱动版本在42.5.0以上,pgvector-java对驱动版本有要求
  3. 如果用Spring Data JPA,确认你的DocumentRepository是正确继承JpaRepository<Document, UUID>

试试上面的方法,应该能解决那个流头错误。我当时用第一种方案直接就搞定了,不用自己折腾自定义类型,省心不少😎

火山引擎 最新活动