使用Hibernate操作PostgreSQL自增主键报hibernate_sequence不存在如何解决?
问题根源
- 初始未配置主键生成策略:未加
@GeneratedValue时Hibernate默认认为主键由业务代码手动赋值,插入SQL会携带id字段,而PostgreSQL的GENERATED ALWAYS约束禁止手动插入id值,触发第一个报错。 - 主键生成策略选择错误:
GenerationType.AUTO在PostgreSQL方言下默认优先使用全局序列hibernate_sequence,你没有手动创建该序列,触发第二个序列不存在的报错。 - 数据类型不匹配:数据库id字段是
bigint类型,对应Java的int类型范围过小,存在溢出风险。 - 缺少无参构造方法:JPA规范要求实体类必须有无参构造方法用于实例化,你当前仅定义了带参构造,会额外引发实例化错误。
- 表名映射可能存在偏差:你贴出的建表语句创建的是
public."user"表,但实体类@Table映射的是portal_user,若实际表名是user需要修正映射规则。
修复方案
步骤1:修正实体类主键配置与基础注解
将User实体类的id字段修改为如下配置,同时补充无参构造注解:
package com.easydefi.users.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Table(name = "\"user\"", schema = "public") // 如果实际表名确实是portal_user,保留原@Table配置即可 @Data @NoArgsConstructor // 补充无参构造,符合JPA规范 public class User implements Serializable { private static final long serialVersionUID = 5062673109048808267L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 指定用数据库IDENTITY自增列生成主键 @Column(name = "id", nullable = false) private Long id; // 改为Long匹配数据库bigint类型 @Column(name = "first_name") private String firstName; @Column(name = "middle_name") private String middleName; @Column(name = "surname") private String surname; public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode, String eMail, String contactNumber, Date createdAt) { super(); this.firstName = firstName; this.middleName = middleName; this.surname = surname; } }
GenerationType.IDENTITY会明确告知Hibernate主键由数据库自增列维护,插入时不会携带id字段,完全符合GENERATED ALWAYS的约束要求。
步骤2:修正Repository泛型类型
因为id字段改为了Long类型,所以Repository的主键泛型也要同步修改:
public interface UsersRepository extends JpaRepository<User, Long> { }
步骤3:配置正确的PostgreSQL方言
在application.properties或application.yml中添加对应版本的PostgreSQL方言配置,确保Hibernate适配数据库特性:
properties格式示例:
# 适配PostgreSQL10及以上版本,可根据实际数据库版本调整 spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL10Dialect
yml格式示例:
spring: jpa: properties: hibernate: dialect: org.hibernate.dialect.PostgreSQL10Dialect
完成以上修改后再运行测试,插入SQL会自动省略id字段,由PostgreSQL的IDENTITY规则自动生成主键,不会再触发报错。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

