Kotlin with JPA / Hibernate: without lazy loading without `open`?

Kotlin example code example is as follows

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

or even

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

Now the Hibernate User Guide , and I think also several other ORMs, say that they usually want to create proxies or otherwise extend the class model, but in order for the class to be explicitly defined open in Kotlin. This is currently not possible with data classes, and I believe from my own experience that most people don’t think about it when writing JPA entities in Kotlin.

So, to answer my question (after all, this is stackoverflow), is it enough to do

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

or we really need to do

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

so as not to interfere with ORM in doing its job properly?
If this is really harmful, we should probably suggest adding an IntelliJ IDEA warning that if the class has @Entity annotation, it should be defined as open .

+5
source share
1 answer

The tutorial below states:

An entity class must have an open or protected constructor without arguments ... An interface cannot be assigned as an object ... An entity class must not be final. No methods or constant variables of an instance of an entity class can be final.

Kotlin classes follow the JavaBeans convention for setters / getters.

If your ORM has requirements as stated above, you really need to specify open for the class and its methods:

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

The default values ​​for all constructor options allow Kotlin to generate an additional empty constructor. Alternatively, you can specify it as a secondary constructor:

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

Note that open val creates a closed end field and an open getter. If this is not enough, use annotations like @JvmField open val name .

ORMs such as the ones you use have additional friction with the Kotlin code due to the dubious design patterns they use (for example, to make everything non-final).

A good option is to use a Kotlin-specific ORM. For example, Exposed is supported by JetBrains and is used for some of its products, which speaks for itself. Another option is Ebean , which officially supports Kotlin (thanks @johnp)

+6
source

All Articles