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")
);
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
)
And then I got UserRepository.kt with the code:
import org.springframework.data.repository.CrudRepository
interface UserRepository : CrudRepository<User, Int>
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
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
)