DEV Community

Cover image for Kotlin, JPA and AUTO_INCREMENT field in DB
Ștefan Vîlce
Ștefan Vîlce

Posted on

Kotlin, JPA and AUTO_INCREMENT field in DB

A small tip about writing model class in Kotlin for one table entity. Let's assume that we have a table in our PostgreSQL database which contains a AUTO_INCREMENT primary key. Let the table be this one:

TABLE users;

CREATE TABLE "public"."users" ( "id" INTEGER NOT NULL, "email" VARCHAR(255) NULL, "name" VARCHAR(255) NULL, "city" VARCHAR(255) NULL, CONSTRAINT "users_pkey" PRIMARY KEY ("id") ); 
Enter fullscreen mode Exit fullscreen mode

The entity model for this table is User.kt with the following code:

import jakarta.persistence.* @Entity @Table(name = "users") data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int, val name: String, val email: String, val city: String ) 
Enter fullscreen mode Exit fullscreen mode

And then I got UserRepository.kt with the code:

import org.springframework.data.repository.CrudRepository interface UserRepository : CrudRepository<User, Int> 
Enter fullscreen mode Exit fullscreen mode

As you can see, I'm using the Hibernate JPA. The application works excellent, but something is wrong. If I try to insert a new user in the table when I use the POST request in the REST API I created (POST: http://localhost:8080/api/users) I get a problem with the error:

 Detail: Key (id)=(1) already exists.] [insert into returning id]; SQL [insert into constraint _pkey]] with root cause 
Enter fullscreen mode Exit fullscreen mode

The issue in code comes from the way I defined the id field.
In JPA/Hibernate entities, the field marked with @GeneratedValue must be mutable (i.e. var), and you usually initialize it with null (or make it Int? in Kotlin).

So, I have to change the code in User.kt as following:

import jakarta.persistence.* @Entity @Table(name = "users") data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int? = null, // it has to be mutable and should be initated as null val name: String, val email: String, val city: String ) 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)