Comme JPA l'exige, les @Entity
classes doivent avoir un constructeur par défaut (non arg) pour instancier les objets lors de leur récupération à partir de la base de données.
Dans Kotlin, les propriétés sont très pratiques à déclarer dans le constructeur principal, comme dans l'exemple suivant:
class Person(val name: String, val age: Int) { /* ... */ }
Mais lorsque le constructeur non-arg est déclaré en tant que constructeur secondaire, il nécessite la transmission de valeurs pour le constructeur principal, donc certaines valeurs valides sont nécessaires pour eux, comme ici:
@Entity
class Person(val name: String, val age: Int) {
private constructor(): this("", 0)
}
Dans le cas où les propriétés ont un type plus complexe que juste String
et Int
et qu'elles ne sont pas Nullable, il semble totalement mauvais de leur fournir les valeurs, surtout quand il y a beaucoup de code dans le constructeur principal et les init
blocs et lorsque les paramètres sont activement utilisés - - quand ils doivent être réaffectés par réflexion, la plupart du code sera à nouveau exécuté.
De plus, val
-properties ne peut pas être réaffecté après l'exécution du constructeur, donc l'immuabilité est également perdue.
La question est donc: comment adapter le code Kotlin pour fonctionner avec JPA sans duplication de code, en choisissant des valeurs initiales "magiques" et en perte d'immuabilité?
PS Est-il vrai que Hibernate en dehors de JPA peut construire des objets sans constructeur par défaut?
INFO -- org.hibernate.tuple.PojoInstantiator: HHH000182: No default (no-argument) constructor for class: Test (class must be instantiated by Interceptor)
- donc, oui, Hibernate peut fonctionner sans le constructeur par défaut.