hibernate - Kotlin 与 JPA/Hibernate : no lazy-loading without `open` ?

标签 hibernate jpa orm lazy-loading kotlin

大多数 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 中,必须显式定义该类 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

最佳答案

您提供的教程指定:

The entity class must have a public or protected no-argument constructor ... Interface may not be designated as an entity ... The entity class must not be final. No methods or persistent instance variables of the entity class may be final.

Kotlin 类遵循 JavaBeans 的 setter/getter 约定。

如果您的 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 创建了一个私有(private)的 final 字段和一个开放的 getter。如果这还不够,请使用像 @JvmField open val name 这样的注解。

像你使用的那样的 ORM 与 Kotlin 代码有额外的摩擦,因为它们使用了有问题的设计模式(比如让所有东西都不是最终的)。

一个不错的选择是使用特定于 Kotlin 的 ORM。例如 Exposed由 JetBrains 支持并用于其某些产品,这不言而喻。另一个选项是 Ebean正式支持 Kotlin(感谢@johnp)

关于hibernate - Kotlin 与 JPA/Hibernate : no lazy-loading without `open` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37733629/

相关文章:

java - 如何将hibernate查询结果添加到数组列表中

java - 使用entityManager加载集合

java - 在 jpql select 中指定列会导致转换错误

java - JPA - 更新 OneToMany-Relations 中的对象

java - 如何强制在 @Entity 和 @ElementCollection 之间生成外键?

java - Hibernate 中 n 个表到 1 个类的运行时单向映射

java - Hibernate - 已持久化子项的 "detached entity passed to persist"错误

spring - Spring boot Data JPA是否在内部使用hibernate来实现?

hibernate - ExampleMatcher.withIgnorePath正在获取被忽略的属性路径

java - 将 hibernate 与泛型一起使用