简体   繁体   中英

How to auto increment the the id in postgersql?

Greeting.. I'm trying to add objects to my PostgreSQL database everything works fine but when i add the second object in the database it only overwrite the first one

Student Class

@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();
        }

    }

My table 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;

the first object is written fine in the database the second one will overwrite the first one

I think your problem is using primitive type for @Id column.

Here what Hibernate says for save() method in javadoc;

Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) This operation cascades to associated instances if the association is mapped with cascade="save-update".

CrudRepository#save() method checks student id, which is 0 for both first and second record, in the database. Since Hibernate founds a record and thinks you're not inserting a record, instead, you're updating a record which it's id is 0.

If you do modify your code like below, it should work;

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

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

Now, Hibernate will check your id and if it's a new record, id field will be null so Hibernate says this is a new record and it should be inserted as a new record.


Also, there is one more thing. You set hbm2ddl.auto in your hibernate configuration. You can check for more detail of hbm2ddl.auto , in here .

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

In this case once CreatStudentDemo works, hibernate destroys your old table. That means, it deletes Student table and creates a new table. Then It creates a Student record in database as expected, let's say Student1.

Here is the thing, you rerun CreatStudentDemo and you expects that the second object would be inserted as Student2. However here is what really happens -- when you rerun CreatStudentDemo hibernate destroys the table which Student1 got deleted. Then it creates Student table and inserts Student objects with an id of 1 because this is the first record on newly created Student table.

Basicly, you can set;

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

or, you can call save() method for two times, like;

        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);
        .....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM