Kotlin与JPA / Hibernate:没有“开放”没有懒加载?

大多数Kotlin JPA示例代码看起来像这样

class Person(val name: String, val age: Int) { /* ... */ } 

甚至

 data class Person(val name: String="", val age: Int=0) { /* ... */ } 

现在, Hibernate用户指南和其他几个ORM都表示,他们通常要创建代理或扩展模型类,但是为了允许在Kotlin中将类明确定义为open 。 这对于数据类来说目前是不可能的,从我自己的经验来看,大多数人在Kotlin编写JPA实体时并没有考虑这个问题。

所以,来我的问题(毕竟这是stackoverflow),是否足够

  open class Person(val name: String, val age: Int) { /* ... */ } 

或者我们真的不得不这样做

  open class Person(open val name: String, open val age: Int) { /* ... */ } 

不是不必要地妨碍ORM正确地完成工作?
如果确实是有害的,我们应该建议给IntelliJ IDEA添加一个警告,如果一个类有一个@Entity注解,它应该被定义为open

您提供的教程指定:

实体类必须有一个公共或保护的无参数构造函数…接口不能被指定为实体…实体类不能是最终的。 没有实体类的方法或持久化实例变量可能是最终的。

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会创建一个私人的最终字段和一个开放的getter。 如果这还不够,请使用@JvmField open val name注释。

由于使用了可疑的设计模式(比如使所有的东西都不是最终的),所以你使用的ORM与Kotlin代码有更多的摩擦。

一个好的选择是使用Kotlin特定的ORM。 例如, Exposed由JetBrains支持,并用于其一些产品,这本身就是一个例子。 另一个选择是正式支持Kotlin的Ebean(感谢@ johnp)

Interesting Posts