【问题标题】:Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint引起:org.postgresql.util.PSQLException:错误:重复键值违反唯一约束
【发布时间】:2021-10-12 03:44:40
【问题描述】:

大家好,我有以下问题:

我有一个用 Spring 编写并使用 PostgreSQL 的后端服务器。起初,一切都很好,但现在我的朋友创建了一个 SQL 脚本,用于用测试数据填充数据库。我们开始吧:

19:46:30,253 INFO  [stdout] (default task-6) Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "user_pkey"
19:46:30,254 INFO  [stdout] (default task-6)   Detail: Key (id)=(1) already exists.
19:46:30,254 INFO  [stdout] (default task-6)    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2497)
19:46:30,254 INFO  [stdout] (default task-6)    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2233)
19:46:30,254 INFO  [stdout] (default task-6)    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310)
19:46:30,254 INFO  [stdout] (default task-6)    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:446)
19:46:30,254 INFO  [stdout] (default task-6)    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:370)
19:46:30,255 INFO  [stdout] (default task-6)    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:149)
19:46:30,255 INFO  [stdout] (default task-6)    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:124)
19:46:30,255 INFO  [stdout] (default task-6)    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
19:46:30,256 INFO  [stdout] (default task-6)    ... 158 more

在该脚本中,我们还为用户提供了一些测试数据。这个错误是在尝试注册时抛出的。我了解,此错误表示我无法将具有现有 ID 的用户保存到数据库中。但我实际上并没有为用户设置 id。当我将用户发送到save() 方法用户id = null 时,我认为Hibernate 应该查看数据库或user_id_sequence 并为当前保存用户选择最后一个id + 1。至少在我们用测试数据填充数据库之前它是这样工作的。问题是为什么 Hibernate 不选择 (last id + 1) 而是尝试使用现有的 id = 0 保存新用户?有什么办法解决吗?

Id 生成策略:

@Getter
@Setter
@MappedSuperclass
@EqualsAndHashCode
@NoArgsConstructor
@ToString(exclude = {"deleted", "updated"})
public class BaseEntity {

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

    // ...
}

休眠配置:

datasource.url=**********
datasource.username=**********
datasource.password=**********
datasource.driver=org.postgresql.Driver
hibernate.show_sql=false
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.batch.size=200
hibernate.hbm2ddl.auto=update

Sql 脚本看起来像一个用测试数据填充数据库的简单脚本:

INSERT INTO public.country (id, created, deleted, updated, code, name, telephone_prefix, continent_id) VALUES (101, NULL, false, NULL, 'ISR', 'Israel', 972, NULL);
....

【问题讨论】:

  • 您是否为表的主键定义了一个序列?如果是这样:您可能希望将生成类型设置为SEQUENCE。详情请见this baeldung article
  • @Turing85 我尝试将策略设置为 GenerationType.SEQUENCE,并使用 SequenceGenerator 创建一个序列。但它没有帮助,我得到:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话相关联
  • 请将表的架构添加到您的问题中。

标签: java spring postgresql hibernate jpa


【解决方案1】:

您是否为种子数据脚本指定了一个 ID?如果您这样做并且它们是正数,您可以尝试将 ID 更改为负数。如果您不指定 ID,您可以尝试指定 ID 并将其设为负数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-15
    • 2016-07-27
    • 2011-10-17
    • 2012-03-03
    • 2018-08-26
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多