大多数Kotlin JPA示例代码都是这样的
class Person(val name: String, val age: Int) { /* ... */ }
甚至
data class Person(val name: String="", val age: Int=0) { /* ... */ }
现在,Hibernate User Guide,我认为还有其他一些ORM,声明他们通常想要创建代理或以其他方式扩展模型类,但是为了在Kotlin中允许它必须明确定义类{{ 1}}。对于数据类来说,目前这是不可能的,从我自己的经验来看,我认为大多数人在Kotlin编写JPA实体时都没有考虑过。
所以,为了解决我的问题(毕竟这是stackoverflow),是否足以做到
open
或者我们真的要做
open class Person(val name: String, val age: Int) { /* ... */ }
不要不必要地阻碍ORM正常工作?
如果确实有害,我们应该建议向IntelliJ IDEA添加警告,如果某个类具有 open class Person(open val name: String, open val age: Int) { /* ... */ }
注释,则应该定义@Entity
。
答案 0 :(得分:7)
您提供的教程指定:
实体类必须具有公共或受保护的无参数构造函数...接口可能不被指定为实体......实体类不能是最终的。实体类的任何方法或持久性实例变量都不是最终的。
Kotlin类遵循JavaBeans惯例来设置setter / getters。
如果您的ORM具有上述要求,那么您确实必须在类及其方法上指定open
:
open class Person(open val name: String = "",
open val age: Int = 0)
所有构造函数参数的默认值允许Kotlin生成另一个空构造函数。或者,您可以将其作为辅助构造函数提供:
open class Person(open val name: String, open val age: Int) {
constructor() : this("", 0)
}
请注意,open val
会创建一个私有的final字段和一个open getter。如果这还不够,请使用@JvmField open val name
等注释。
你使用的ORM与Kotlin代码有额外的摩擦,因为他们使用了可疑的设计模式(比如让所有东西都不是最终的)。
一个好的选择是使用Kotlin特定的ORM。例如,JetBrains支持Exposed并用于其中的一些产品,这些产品本身就说明了问题。另一个选项是Ebean,正式支持Kotlin(感谢@johnp)