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

Ștefan Vîlce @vilce

About: Technology, cycling, running

Location:
Oslo
Joined:
May 15, 2019

Kotlin, JPA and AUTO_INCREMENT field in DB

Publish Date: Aug 26
0 0

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

Comments 0 total

    Add comment