【发布时间】:2018-04-10 07:32:44
【问题描述】:
什么是定义 JPA 实体 ID 的“kotlin 方式”?
@Entity
data class User (
@Id @GeneratedValue
var id: Long? = null,
...
)
或者有没有更好的方法来避免可以为空的 id?
【问题讨论】:
什么是定义 JPA 实体 ID 的“kotlin 方式”?
@Entity
data class User (
@Id @GeneratedValue
var id: Long? = null,
...
)
或者有没有更好的方法来避免可以为空的 id?
【问题讨论】:
您可以使用 0 值而不是空值。
@Entity
data class User (
@Id @GeneratedValue
var id: Long = 0,
...
)
自动生成仍应找到下一个序列。
Kotlin 编译为 Java,它同时具有基本类型 long 和类 Long
根据11.1.21 Id Annotation部分中的Java Persistence Specification,两者都可以用于Id:
应用Id注解的字段或属性应该是1 以下类型:任何 Java原始类型;任何原始包装类型; java.lang.String; java.util.日期; java.sql.日期; java.math.BigDecimal; java.math.BigInteger[109].
与原语相比,使用 Class 有一个优势,因为 null 具有更明确的含义。但是从规范来看,两者都是可能的,你必须决定你喜欢 Kotlins nullsafety 而不是 jpa 风格或其他方式的天气。
【讨论】:
UUID(0,0) 用虚拟值初始化 id 变量,当将对象保存到数据库时,自动生成器将覆盖该变量
通常,数据类可用于从方法中返回多个结果,但不适用于实体(仅我的观点)。
有时为 id 字段设置默认值并不是一个好主意。
在对 Kotlin 和实体进行了一段时间的试验后(实际上,使用了 MongoDb 的文档,但无论如何它都有 id),
看起来更好的方法是使用lateinit var。您可以创建实体层次结构的顶级类:
open class Identifiable {
lateinit var id: Long // or String or UUID
//explicitly define equals & hash code here
}
但是要小心,对于equals,hashcode,如果你想在继承者中提供toString方法,那么提供额外的可空字段是个好主意,比如:
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})"
}
在这种情况下,当您尝试记录您创建但未保存在数据库实体中时,您将避免异常
【讨论】: