Kotlin con JPA / Hibernate: sin carga lenta sin `abrir`?

La mayoría del código de ejemplo de Kotlin JPA se ve así

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

o incluso

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

Ahora, la Guía del usuario de Hibernate , y creo que también varios otros ORM, afirman que generalmente quieren crear proxies o ampliar la class de model, pero para permitir que en Kotlin la class tenga que definirse explícitamente como open . Esto es actualmente imposible con las classs de datos y supongo, a juzgar por mi propia experiencia, que la mayoría de la gente no piensa en ello cuando escribe entidades JPA en Kotlin.

Entonces, para llegar a mi pregunta (esto es stackoverflow después de todo), ¿es suficiente hacer

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

o realmente tendríamos que hacer

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

para no obstaculizar innecesariamente al ORM al hacer su trabajo correctamente?
Si realmente es dañino, probablemente deberíamos proponer agregar una advertencia a IntelliJ IDEA, que si una class tiene una anotación @Entity , debe definirse open .

El tutorial que proporcionó especifica:

La class de entidad debe tener un constructor de no arguments público o protegido … La interfaz no se puede designar como una entidad … La class de entidad no debe ser definitiva. Ningún método o variable de instancia persistente de la class de entidad puede ser final.

Las classs de Kotlin siguen la convención de JavaBeans para setters / getters.

Si su ORM tiene requisitos como el anterior, entonces de hecho debe especificar open en la class y sus methods:

 open class Person(open val name: String = "", open val age: Int = 0) 

Los valores pnetworkingeterminados para todos los parameters del constructor permiten a Kotlin generar un constructor vacío adicional. Alternativamente, puede proporcionarlo como un constructor secundario:

 open class Person(open val name: String, open val age: Int) { constructor() : this("", 0) } 

Tenga en count que open val crea un campo final privado y un getter abierto. Si eso no es suficiente, use annotations como @JvmField open val name .

Los ORM como los que usa tienen fricciones adicionales con el código de Kotlin debido a los cuestionables patrones de layout que usan (como hacer que todo no sea definitivo).

Una buena opción es usar un ORM específico de Kotlin. Por ejemplo, Exposed es compatible con JetBrains y se usa para algunos de sus productos, lo que habla por sí mismo. Otra opción es Ebean que oficialmente apoya a Kotlin (gracias @johnp)