Как автоматически увеличить идентификатор в postgersql? - PullRequest
0 голосов
/ 20 сентября 2019

Приветствие .. Я пытаюсь добавить объекты в свою базу данных PostgreSQL, все работает нормально, но когда я добавляю второй объект в базу данных, он перезаписывает только первый

Студенческий класс

@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(columnDefinition="serial")
    private int id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="email")
    private String email;
public Student() {

    }

    public Student(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.username">user1</property>
        <property name="hibernate.connection.password">test123</property>
        <property name="hibernate.connection.url">jdbc:postgresql://127.0.0.1:5432/hb_student_tracker</property>

        <property name="hibernate.current_session_context_class">thread</property>

        <property name="connection_pool_size">1</property>

        <property name="hbm2ddl.auto">create</property>

        <property name="show_sql">true</property>

    </session-factory>
</hibernate-configuration>

CreatStudentDemo.java

public static void main(String[] args) {


        //create session Factory
        SessionFactory factory = new Configuration()
                .configure()
                .addAnnotatedClass(Student.class)
                .buildSessionFactory();


        //create Session
        Session session = factory.getCurrentSession();




        try {

            System.out.println("Creating new Studnet Object..");
            //create Student Object
            Student student = new Student("Souid","Ayoub","ayoub@luv2code.com");

            //start the transaction
            session.beginTransaction();

            //save the object
            System.out.println("Saving the Student...");
            session.save(student);

            //commit the transaction
            session.getTransaction().commit();
            System.out.println("Done !");
        } finally {
            factory.close();
        }

    }

Моя таблица SQL

CREATE TABLE public.student
(
    id integer NOT NULL DEFAULT nextval('student_id_seq'::regclass),
    email character varying(255) COLLATE pg_catalog."default",
    first_name character varying(255) COLLATE pg_catalog."default",
    last_name character varying(255) COLLATE pg_catalog."default",
    CONSTRAINT student_pkey PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.student
    OWNER to user1;

первый объект отлично записывается в базу данныхвторой перезапишет первый

1 Ответ

3 голосов
/ 20 сентября 2019

Я думаю, что ваша проблема в использовании примитивного типа для столбца @Id.

Вот что говорит Hibernate для метода save() в javadoc;

Сохраняет данный временный экземпляр, сначала назначая сгенерированный идентификатор.(Или используя текущее значение свойства идентификатора, если используется назначенный генератор.) Эта операция распространяется каскадно на связанные экземпляры, если сопоставление отображается с помощью cascade = "save-update".

CrudRepository#save()Метод проверяет идентификатор студента, который равен 0 для первой и второй записи, в базе данных.Поскольку Hibernate находит запись и думает, что вы не вставляете запись, вместо этого вы обновляете запись с идентификатором 0.

Если вы измените свой код, как показано ниже, это должно сработать;

@Entity
@Table(name = "student")
public class Student {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(columnDefinition="serial")
  private Integer id;

Теперь Hibernate проверит ваш идентификатор, и если это новая запись, поле id будет нулевым, поэтому Hibernate говорит, что это новая запись, и ее следует вставить как новую запись.


Кроме того, есть еще одна вещь.Вы устанавливаете hbm2ddl.auto в своей конфигурации гибернации.Вы можете проверить более подробную информацию о hbm2ddl.auto, здесь .

<property name="hbm2ddl.auto">create</property>

В этом случае, когда CreatStudentDemo работает, hibernate уничтожает вашу старую таблицу.Это означает, что он удаляет таблицу Student и создает новую таблицу.Затем он создает запись Student в базе данных, как и ожидалось, скажем Student1.

Вот эта вещь, вы повторно запускаете CreatStudentDemo и ожидаете, что второй объект будет вставлен как Student2.Однако вот что происходит на самом деле - при повторном запуске CreatStudentDemo hibernate уничтожает таблицу, которую Student1 удалил.Затем он создает таблицу Student и вставляет объекты Student с идентификатором 1, потому что это первая запись во вновь созданной таблице Student.

Как правило, вы можете установить;

<property name="hbm2ddl.auto">update</property>

илиможет вызвать save() метод два раза, например;

        Student student = new Student("Souid","Ayoub","ayoub@luv2code.com");
        Student student2 = new Student("Test Student","TestStudent","test@mail.com");

        //start the transaction
        session.beginTransaction();

        //save the object
        System.out.println("Saving the Student...");
        session.save(student);
        session.save(student2);
        .....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...