Как требует JPA, @Entity
классы должны иметь конструктор по умолчанию (без аргументов) для создания экземпляров объектов при их извлечении из базы данных.
В Kotlin свойства очень удобно объявлять в основном конструкторе, как в следующем примере:
class Person(val name: String, val age: Int) { /* ... */ }
Но когда конструктор без аргументов объявляется как вторичный, он требует передачи значений для первичного конструктора, поэтому для них необходимы некоторые допустимые значения, как здесь:
@Entity
class Person(val name: String, val age: Int) {
private constructor(): this("", 0)
}
В случае, когда свойства имеют более сложный тип, чем просто String
и, Int
и они не допускают значения NULL, выглядит совершенно плохим предоставление значений для них, особенно когда в первичном конструкторе и init
блоках много кода и когда параметры активно используются - - когда они будут переназначены посредством отражения, большая часть кода будет выполнена снова.
Более того, val
-properties нельзя переназначить после выполнения конструктора, поэтому неизменяемость также теряется.
Возникает вопрос: как адаптировать код Kotlin для работы с JPA без дублирования кода, выбора «волшебных» начальных значений и потери неизменяемости?
PS Верно ли, что Hibernate помимо JPA может создавать объекты без конструктора по умолчанию?
INFO -- org.hibernate.tuple.PojoInstantiator: HHH000182: No default (no-argument) constructor for class: Test (class must be instantiated by Interceptor)
- так что да, Hibernate может работать без конструктора по умолчанию.