Why am I obtaining this error related the auto increment PK of a PosgreSQL table using Hibernate? ERROR: relation "hibernate_sequence" does not exist
Why am I obtaining this error related the auto increment PK of a PosgreSQL table using Hibernate? ERROR: relation "hibernate_sequence" does not exist
我正在使用 Spring Data JPA 开发 Spring Boot 应用程序。
作为数据库,我正在使用 PostgreSQL,我发现一些问题将 table 的自动递增主键字段映射到我的实体 class.
的相关字段
在我的数据库中,我手动创建了这个 table:
CREATE TABLE IF NOT EXISTS public."user"
(
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
first_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
middle_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
surname character varying(50) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT user_pkey PRIMARY KEY (id)
)
请注意,id 字段(我的 PK)被定义为 bigint,GENERATED ALWAYS 约束而不是 serial(这是因为串行数据类型已被弃用,因为它不是 SQL 标准的一部分)。
然后我创建了这个实体 class 映射这个 table:
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;
@Entity
@Table(name = "portal_user")
@Data
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
@Id
@Column(name = "id")
private int id;
@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;
}
}
然后我有这个存储库接口(目前它是空的,因为我只测试save()直接由JpaRepository[=48提供的方法=]):
public interface UsersRepository extends JpaRepository<User, Integer> {
}
最后,我创建了这个简单的单元测试方法,以便通过我存储库的 save() 方法测试新记录的插入:
@SpringBootTest()
@ContextConfiguration(classes = GetUserWsApplication.class)
@TestMethodOrder(OrderAnnotation.class)
public class UserRepositoryTest {
@Autowired
private UsersRepository userRepository;
@Test
@Order(1)
public void testInsertUser() {
User user = new User("Mario", null, "Rossi", 'M', new Date(), "XXX", "xxx@gmail.com", "329123456", new Date());
userRepository.save(user);
assertTrue(true);
}
}
问题是,当执行 save() 方法时,我得到了这个异常:
Hibernate:
insert
into
portal_user
(first_name, middle_name, surname, id)
values
(?, ?, ?, ?)
2021-11-04 12:17:39.576 WARN 11436 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 428C9
2021-11-04 12:17:39.578 ERROR 11436 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: cannot insert a non-DEFAULT value into column "id"
Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Hint: Use OVERRIDING SYSTEM VALUE to override.
所以我尝试修改id字段到我的实体class的映射,这样:
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
但是 运行 我的测试方法现在 save() 方法执行给我另一个错误:
Hibernate:
select
nextval ('hibernate_sequence')
2021-11-04 12:20:21.133 WARN 11639 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2021-11-04 12:20:21.136 ERROR 11639 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
Position: 17
有什么问题?我错过了什么?我该如何解决这个问题?
错误肯定在这一行。
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
如果您想快速修复,可以将其更改为下面的。
SERIAL
在 Postgres 中工作得很好。当然,它可能不会 运行 在其他数据库上,但是 IT 项目多久进行一次数据库迁移?从来没有。
id serial PRIMARY KEY NOT NULL,
这能解决您的问题吗?或者你出于某种原因需要在没有 SERIAL 的情况下解决它?
改变
GeneratedValue(strategy=GenerationType.AUTO)
至
@GeneratedValue(strategy=GenerationType.IDENTITY)
因为 GenerationType.IDENTITY
使用未手动修改的 auto increment
创建 primary key
。
我正在使用 Spring Data JPA 开发 Spring Boot 应用程序。 作为数据库,我正在使用 PostgreSQL,我发现一些问题将 table 的自动递增主键字段映射到我的实体 class.
的相关字段在我的数据库中,我手动创建了这个 table:
CREATE TABLE IF NOT EXISTS public."user"
(
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
first_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
middle_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
surname character varying(50) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT user_pkey PRIMARY KEY (id)
)
请注意,id 字段(我的 PK)被定义为 bigint,GENERATED ALWAYS 约束而不是 serial(这是因为串行数据类型已被弃用,因为它不是 SQL 标准的一部分)。
然后我创建了这个实体 class 映射这个 table:
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;
@Entity
@Table(name = "portal_user")
@Data
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
@Id
@Column(name = "id")
private int id;
@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;
}
}
然后我有这个存储库接口(目前它是空的,因为我只测试save()直接由JpaRepository[=48提供的方法=]):
public interface UsersRepository extends JpaRepository<User, Integer> {
}
最后,我创建了这个简单的单元测试方法,以便通过我存储库的 save() 方法测试新记录的插入:
@SpringBootTest()
@ContextConfiguration(classes = GetUserWsApplication.class)
@TestMethodOrder(OrderAnnotation.class)
public class UserRepositoryTest {
@Autowired
private UsersRepository userRepository;
@Test
@Order(1)
public void testInsertUser() {
User user = new User("Mario", null, "Rossi", 'M', new Date(), "XXX", "xxx@gmail.com", "329123456", new Date());
userRepository.save(user);
assertTrue(true);
}
}
问题是,当执行 save() 方法时,我得到了这个异常:
Hibernate:
insert
into
portal_user
(first_name, middle_name, surname, id)
values
(?, ?, ?, ?)
2021-11-04 12:17:39.576 WARN 11436 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 428C9
2021-11-04 12:17:39.578 ERROR 11436 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: cannot insert a non-DEFAULT value into column "id"
Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Hint: Use OVERRIDING SYSTEM VALUE to override.
所以我尝试修改id字段到我的实体class的映射,这样:
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
但是 运行 我的测试方法现在 save() 方法执行给我另一个错误:
Hibernate:
select
nextval ('hibernate_sequence')
2021-11-04 12:20:21.133 WARN 11639 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2021-11-04 12:20:21.136 ERROR 11639 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
Position: 17
有什么问题?我错过了什么?我该如何解决这个问题?
错误肯定在这一行。
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
如果您想快速修复,可以将其更改为下面的。
SERIAL
在 Postgres 中工作得很好。当然,它可能不会 运行 在其他数据库上,但是 IT 项目多久进行一次数据库迁移?从来没有。
id serial PRIMARY KEY NOT NULL,
这能解决您的问题吗?或者你出于某种原因需要在没有 SERIAL 的情况下解决它?
改变
GeneratedValue(strategy=GenerationType.AUTO)
至
@GeneratedValue(strategy=GenerationType.IDENTITY)
因为 GenerationType.IDENTITY
使用未手动修改的 auto increment
创建 primary key
。