【发布时间】: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