使用 Hibernate 在 PostgreSQL 中添加项目时不会发生自动递增

Auto incrementing does not occur when adding an item in PostgreSQL using Hibernate

提问人:Артем Лебідь 提问时间:7/18/2023 更新时间:7/26/2023 访问量:45

问:

我在PostgeSQL中创建了一个包含个人数据的表,并将类型为“SERIAL”的列“id”标记为“主键”,“not null”

CREATE 脚本:

CREATE TABLE people (
  id serial NOT NULL,
  name varchar(15),
  surname varchar(25),
  department varchar(20),
  salary int,
  PRIMARY KEY (id)
);

然后,我为我的表创建了一个 Entity 类

package hibernate_test.entity;
import jakarta.persistence.*;

@Entity
@Table(name = "people")
public class Employee {
    @Id
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "surname")
    private String surname;
    @Column(name = "department")
    private String department;
    @Column(name = "salary")
    private int salary;

    public Employee() {
    }

    public Employee(String name, String surname, String department, int salary) {
        this.name = name;
        this.surname = surname;
        this.department = department;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", surname='" + surname + '\'' +
                ", department='" + department + '\'' +
                ", salary=" + salary +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

接下来,我编写了一个程序,将记录添加到我的表中

package hibernate_test;

import hibernate_test.entity.Employee;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test1 {
    public static void main(String[] args) {
        SessionFactory factory = new Configuration()
                .configure("hibernate.cfg.xml")
                .addAnnotatedClass(Employee.class)
                .buildSessionFactory();

        Session session = factory.getCurrentSession();
        Employee emp = new Employee("Jack", "Jack", "IT", 5000);

        try {
            session.beginTransaction();
            session.save(emp);
            session.getTransaction().commit();

        }finally {
            factory.close();
        }

    }
}

当我运行此代码时,第一条记录将添加到表中,但 id 位于索引 0 处。我认为索引应该从 1 开始,因为我在 id 中指定了类型“SERIAL”。 当我尝试添加其他项目时,发生错误:

09:09:05.911 [main] INFO org.hibernate.Version -- HHH000412: Hibernate ORM core version 6.2.6.Final
09:09:05.916 [main] INFO org.hibernate.cfg.Environment -- HHH000406: Using bytecode reflection optimizer
09:09:06.366 [main] WARN org.hibernate.orm.connections.pooling -- HHH10001002: Using built-in connection pool (not intended for production use)
09:09:06.369 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001005: Loaded JDBC driver class: org.postgresql.Driver
09:09:06.369 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001012: Connecting with JDBC URL [jdbc:postgresql://127.0.0.1:5432/learnhbn]
09:09:06.369 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001001: Connection properties: {password=****, user=postgres}
09:09:06.369 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001003: Autocommit mode: false
09:09:06.373 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001115: Connection pool size: 20 (min=1)
09:09:06.796 [main] INFO org.hibernate.bytecode.internal.BytecodeProviderInitiator -- HHH000021: Bytecode provider name : bytebuddy
Hibernate: insert into people (department,name,salary,surname,id) values (?,?,?,?,?)
09:09:07.648 [main] WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper -- SQL Error: 0, SQLState: 23505
09:09:07.648 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper -- ПОМИЛКА: повторювані значення ключа порушують обмеження унікальності "people_pkey"
  Подробности: Ключ (id)=(0) вже існує.
09:09:07.656 [main] INFO org.hibernate.orm.connections.pooling -- HHH10001008: Cleaning up connection pool [jdbc:postgresql://127.0.0.1:5432/learnhbn]
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement [ПОМИЛКА: повторювані значення ключа порушують обмеження унікальності "people_pkey"
  Подробности: Ключ (id)=(0) вже існує.] [insert into people (department,name,salary,surname,id) values (?,?,?,?,?)]
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:95)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:278)
    at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:108)
    at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:40)
    at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:53)
    at org.hibernate.persister.entity.mutation.InsertCoordinator.doStaticInserts(InsertCoordinator.java:170)
    at org.hibernate.persister.entity.mutation.InsertCoordinator.coordinateInsert(InsertCoordinator.java:112)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2761)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:102)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:633)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:502)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:358)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1412)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:485)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2301)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1966)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:169)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:267)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
    at hibernate_test.Test1.main(Test1.java:21)
Caused by: org.postgresql.util.PSQLException: ПОМИЛКА: повторювані значення ключа порушують обмеження унікальності "people_pkey"
  Подробности: Ключ (id)=(0) вже існує.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2713)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2401)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:368)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:498)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:415)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190)
    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:152)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:275)
    ... 21 more

Process finished with exit code 1

该错误指示不能有两条索引为 0 的记录,但我没有将任何 id 值直接传递给构造函数。Hibernate 应该将 id 递增为 1,理想情况下从 1 开始

如果你能帮我弄清楚我在哪里犯了错误,我会很高兴

java postgresql 休眠 自动增量

评论

1赞 M. Deinum 7/18/2023
您没有在现场指定策略。那里应该有一个指示休眠数据库将生成标识符。@Id@GeneratedValue
0赞 Laurenz Albe 7/18/2023
如果将列创建为 ,则会看到 Hibernate 尝试插入。id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY
0赞 Артем Лебідь 7/18/2023
@M. Deinum 当我添加“@GeneratedValue”注释时,我收到以下错误 原因:org.postgresql.util.PSQLException:错误:“newtable_seq”关系不存在 位置:16
0赞 M. Deinum 7/18/2023
你需要告诉它它使用 IDENTITY,而不是 AUTO 或 SEQUENCE。
0赞 Артем Лебідь 7/18/2023
@M. Deinum,我感激不尽!

答:

1赞 Артем Лебідь 7/22/2023 #1

M. Deinum 的回答:

您没有在现场指定策略。那里应该有一个指示 Hibernate 数据库将生成标识符。@Id@GeneratedValue