Spring Boot 3 + Hibernate 6中如何支持PostgreSQL的pgvector扩展?
Spring Boot 3 + Hibernate 6 适配PostgreSQL pgvector向量扩展
问题原因
你遇到的PSQLException是因为自定义Converter仅做了字符串与向量的转换,但Hibernate仍将其以varchar类型发送给数据库,与PostgreSQL的vector原生类型不匹配,导致类型转换错误。
解决方案
1. 添加依赖
引入pgvector Java客户端和适配的PostgreSQL JDBC驱动:
<!-- Maven依赖 --> <dependency> <groupId>com.github.pgvector</groupId> <artifactId>pgvector-java</artifactId> <version>0.10.0</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> </dependency>
2. 自定义Hibernate向量类型
创建适配pgvector的Hibernate基础类型,让框架正确识别数据库的vector类型:
import com.github.pgvector.Vector; import com.github.pgvector.VectorTypeDescriptor; import org.hibernate.type.AbstractSingleColumnStandardBasicType; import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; public class PgVectorType extends AbstractSingleColumnStandardBasicType<Vector> { public static final PgVectorType INSTANCE = new PgVectorType(); public PgVectorType() { super(VarcharTypeDescriptor.INSTANCE, VectorTypeDescriptor.INSTANCE); } @Override public String getName() { return "vector"; } }
3. 配置JPA实体
在实体类中注册自定义类型,并映射向量字段:
import com.github.pgvector.Vector; import jakarta.persistence.*; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @Entity @Table(name = "items") @TypeDef(name = "vector", typeClass = PgVectorType.class) // 注册自定义类型 public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(columnDefinition = "vector(5)") @Type(type = "vector") // 使用自定义类型映射字段 private Vector embedding; // Getter & Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Vector getEmbedding() { return embedding; } public void setEmbedding(Vector embedding) { this.embedding = embedding; } }
4. 注册JDBC类型映射(可选但推荐)
在Spring配置类中注册pgvector的JDBC类型映射,确保驱动能正确处理vector类型:
import com.github.pgvector.Vector; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @Component public class PgVectorConfig { @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String dbUser; @Value("${spring.datasource.password}") private String dbPassword; @PostConstruct public void registerVectorType() throws SQLException { try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) { conn.getTypeMap().put("vector", Vector.class); } } }
5. 业务代码示例
直接使用pgvector的Vector类创建向量并保存:
import com.github.pgvector.Vector; import org.springframework.stereotype.Service; import jakarta.transaction.Transactional; @Service public class ItemService { private final ItemRepository itemRepository; public ItemService(ItemRepository itemRepository) { this.itemRepository = itemRepository; } @Transactional public void saveWithEmbedding() { float[] embeddingValues = {1.2f, 3.4f, 5.6f, 7.8f, 9.0f}; Vector embedding = new Vector(embeddingValues); Item item = new Item(); item.setEmbedding(embedding); itemRepository.save(item); } }
内容的提问来源于stack exchange,提问作者K. Meyer
相关产品推荐
相关产品推荐

