Como JPA requiere, las @Entity
clases deben tener un constructor predeterminado (no arg) para instanciar los objetos al recuperarlos de la base de datos.
En Kotlin, es muy conveniente declarar las propiedades dentro del constructor primario, como en el siguiente ejemplo:
class Person(val name: String, val age: Int) { /* ... */ }
Pero cuando el constructor no arg se declara como secundario, requiere valores para que se pase el constructor primario, por lo que se necesitan algunos valores válidos para ellos, como aquí:
@Entity
class Person(val name: String, val age: Int) {
private constructor(): this("", 0)
}
En caso de que las propiedades tengan un tipo más complejo que solo String
y Int
no sean anulables, se ve totalmente mal proporcionarles los valores, especialmente cuando hay mucho código en el constructor primario y los init
bloques y cuando los parámetros se usan activamente: - cuando van a reasignarse mediante reflexión, la mayor parte del código se ejecutará nuevamente.
Además, las val
propiedades no se pueden reasignar después de que se ejecuta el constructor, por lo que también se pierde la inmutabilidad.
Entonces la pregunta es: ¿cómo se puede adaptar el código de Kotlin para trabajar con JPA sin duplicación de código, eligiendo valores iniciales "mágicos" y pérdida de inmutabilidad?
PD ¿Es cierto que Hibernate aparte de JPA puede construir objetos sin un constructor predeterminado?
INFO -- org.hibernate.tuple.PojoInstantiator: HHH000182: No default (no-argument) constructor for class: Test (class must be instantiated by Interceptor)
- Entonces, sí, Hibernate puede funcionar sin el constructor predeterminado.