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)被定义为 bigintGENERATED 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