Postgresql 在“id”列中抛出空值违反了 GenerationType.IDENTITY 的非空约束

Posted

技术标签:

【中文标题】Postgresql 在“id”列中抛出空值违反了 GenerationType.IDENTITY 的非空约束【英文标题】:Postgresql throws null value in column "id" violates not-null constraint for GenerationType.IDENTITY 【发布时间】:2021-01-15 12:00:02 【问题描述】:

我正在尝试为我的实体自动生成 ID:

public class User 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

我的DB表是通过flyway脚本创建的,列ID设置为IDENTITY

CREATE TABLE USERS (
   ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
   PRIMARY KEY (ID)
;

然后我试图用我的存储库保存这个实体:

@Repository
public interface UserRepository extends JpaRepository<User, Long> 

像这样:

userRepository.save(user);

然而这会导致错误

“id”列中的空值违反非空约束

这仅在连接到 PostgreSQL:12.2 时显示,如果我使用 h2 数据库运行相同的代码,它可以正常工作。

为什么这在 PostgreSQL 中失败了?

【问题讨论】:

适用于我的 Hibernate 5.4 【参考方案1】:

您应该创建序列并将该序列用作 id

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
    @SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq")
    private long id;

你应该在 postgresql 中创建序列:

CREATE SEQUENCE user_id_seq
INCREMENT 5
START 10;

【讨论】:

一个identity 列已经有一个序列,Hibernate 应该足够聪明以支持GenerationType.IDENTITY 注释 - 这闻起来像一个 Hibernate 错误。使用正确的identity 列是正确的(Postgres)方法。 我认为hibernate在数据库中搜索正确的序列,当它找不到合适的序列时,它可能会失败,但我同意你的观点,hibernate不够聪明 Hibernate 根本不应该发送任何值,例如生成 insert into users (name) values ('bla') - 这就是 Hibernate (5.4) 在我的代码中所做的 你使用哪个版本的休眠? 我在 postgres 邮件列表中找到了这个 postgresql.org/message-id/…【参考方案2】:

制作用户表

创建表用户 ( ID 序列号 NOT NULL 默认为 IDENTITY 生成, 主键 (ID) ;

【讨论】:

这与问题中的 CREATE TABLE 语句有何不同?

以上是关于Postgresql 在“id”列中抛出空值违反了 GenerationType.IDENTITY 的非空约束的主要内容,如果未能解决你的问题,请参考以下文章

我应该在私有/内部方法中抛出空参数吗?

注册方法在我的控制器类中抛出空指针异常

在带有 postgres 数据库的 jbpm 6.5.0Final 中出现错误:“id”列中的空值违反了非空约束

错误:关系 xxx 的“id”列中的空值违反非空约束 - Spring Data JPA

Django - 列中的空值违反了 Django Admin 中的非空约束

“last_login”列中的空值违反非空约束