英文:
Auto incrementing does not occur when adding an item in PostgreSQL using Hibernate
问题
我在PostgreSQL中创建了一个包含个人数据的表,并将列 "id" 标记为类型 'SERIAL' 和 '主键','非空'。
以下是创建脚本:
CREATE TABLE people (
id serial NOT NULL,
name varchar(15),
surname varchar(25),
department varchar(20),
salary int,
PRIMARY KEY (id)
);
然后,我为我的表创建了一个实体类:
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。我认为id应该从1开始,因为我在id中指定了类型 'SERIAL'。当我尝试添加另一项时,出现错误:
错误表明不能有两条id为0的记录,但我没有直接将id值传递给构造函数。Hibernate应该自己递增id,并且理想情况下从1开始。
如果可以的话,我会很高兴帮助你找出我哪里出错了。
英文:
I created a table in PostgeSQL with data for a person and marked the column "id" with the type 'SERIAL' as 'primary key', 'not null'
CREATE Script:
CREATE TABLE people (
id serial NOT NULL,
name varchar(15),
surname varchar(25),
department varchar(20),
salary int,
PRIMARY KEY (id)
);
Then I created an Entity class for my table
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;
}
}
Next, I wrote a program that adds a record to my table
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();
}
}
}
When I run this code, the first record is added to the table, but the id is at index 0. I think the index should start at 1 because I specified the type 'SERIAL' in the id.
When I try to add another item, an error occurs:
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
The error indicates that there can't be two records with index 0, but I don't pass any id value directly to the constructor. Hibernate should increment the id to one itself, and ideally start with one
I will be glad if you can help me figure out where I am making a mistake
答案1
得分: 1
答复来自 M. Deinum:
您没有在 @Id
字段上指定策略。应该在那里使用 @GeneratedValue
来告诉Hibernate数据库会生成标识符。
英文:
Answer from M. Deinum:
You didn't specify a strategy on the @Id
field. There should be an @GeneratedValue
on there to indicate to Hibernate that the database will generate the identifier.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论