What is "the kotlin way" to define JPA entity ID?
@Entity
data class User (
@Id @GeneratedValue
var id: Long? = null,
...
)
Or is there any better one to avoid nullable id?
What is "the kotlin way" to define JPA entity ID?
@Entity
data class User (
@Id @GeneratedValue
var id: Long? = null,
...
)
Or is there any better one to avoid nullable id?
You can use a 0 value rather than a null value.
@Entity
data class User (
@Id @GeneratedValue
var id: Long = 0,
...
)
Autogeneration should still find the next sequence.
Kotlin compiles to Java, which has both, a primitive type long
and a Class Long
As per the Java Persistence Specification in section 11.1.21 Id Annotation both can be used for the Id:
The field or property to which the Id annotation is applied should be one of the following types: any Java primitive type; any primitive wrapper type; java.lang.String; java.util.Date; java.sql.Date; java.math.BigDecimal; java.math.BigInteger[109].
There is an advantage in using the Class over the primitive, as null
has a more unambiguous meaning. But from the spec both are possible and you have to decide weather you favor Kotlins nullsafety over the the jpa style or the other way around.
Usually, data class is useful to ruturn more that one result from a method , but not for entities (just my opinion).
Sometimes it is not a good idea to set a default value for the id field.
After some time experimenting with Kotlin and entities (actually, with documents for MongoDb, but anyway it has id),
Looks like the better way is to use lateinit var
. You can create the top class of entity hierarchy:
open class Identifiable {
lateinit var id: Long // or String or UUID
//explicitly define equals & hash code here
}
But be careful, for equals, hashcode and if you want to provide toString method in heirs, then it is a good idea to provide extra nullable field, something like:
open class Identifiable {
lateinit var id: Long // or String or UUID
val nullableId: Long?
get() {
return if(this::id.isInitialized) id else null
}
//explicitly define equals & hash code here with nullableId
}
class User {
override fun toString() = "User(id=${nullableId})"
}
In this case, you will avoid an exception when you will try to log your created but not saved in DB entity