How to use Hibernate 5 to insert Postgresql auto incrementing primary key

Postgresql does not have auto_increment keyword functionality on table creation as in mySQL.

The best way to do is to use SERIAL or BIGSERIAL data type on the primary key.

Serial data type act as an auto increment sequence in the background.

This automatically created sequence usually has following name pattern: student_id_seq

You can create a simple table with auto incrementing primary key as bellow in postgresql 9.x:

CREATE TABLE student (
    id serial NOT NULL ,
    first_name character varying(45),
    last_name character varying(45), 
    email character varying(45), 
    CONSTRAINT student_pkey PRIMARY KEY (id) 
)

This will automatically create a sequence called student_id_seq in the background, which will increment the id value by 1 with each increment.

When inserting data to the table using SQL you don't need to give any value for the ID

You can simply insert data using

insert into student(first_name, last_name, email) values ('test','test','test')



If you are doing it for the first time, persisting data using hibernate to a table like above will be tricky.

In a non postgresql scenario you can create an entity class and create an id field as follows to persist data to the given table using Hibernate 5.

@Id
@Column(name="id", unique=true, nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

But for a postgresql DB above code will result in following exceptions:

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: Could not set field value [POST_INSERT_INDICATOR] value by reflection : [class com.hibernate.demo.entity.Student.id] setter of com.hibernate.demo.entity.Student.id

Caused by: org.hibernate.PropertyAccessException: Could not set field value [POST_INSERT_INDICATOR] value by reflection : [class com.hibernate.demo.entity.Student.id] setter of com.hibernate.demo.entity.Student.id



Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.hibernate.demo.entity.Student.id to org.hibernate.id.IdentifierGeneratorHelper$2


To solve this issue, we need to make sure hibernate know about the automatically created sequence in postgresql (i.e student_id_seq). Therefore we need to change our ID field annotation to the following.

@Id 
@SequenceGenerator(name="pk_sequence",sequenceName="student_id_seq", allocationSize=1) @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence") @Column(name="id", unique=true, nullable=false)
private int id;

Above will make sure that hibernate know that id is a generated value, it is a sequence and unique.

Hope this helped 😆

Comments

Popular posts from this blog

How to unlock 2Degrees Fritzbox to be used in any other Fibre Network

Postgresql , Hibernate and issues with Schemas