Источники:
Object,Companion Object https://bimlibik.github.io/posts/kotlin-object-keyword/
Kotlin + JPA Kotlin + Hibernate: всё сложно.
Классы данных(data class) — не лучший вариант для сущностей, т.к:
1. Класс сущности должен иметь конструктор без параметров. Класс сущности также может иметь другие конструкторы. Конструктор без параметров должен быть public или protected. Без него Hibernate не сможет создавать экземпляры сущности и будет бросать исключение: org.hibernate.InstantiationException: No default constructor for entity. Можно вручную определить конструктор без параметров для всех сущностей в проекте. Но есть плагин для компилятора kotlin-jpa. Чтобы включить kotlin-jpa, его надо добавить в зависимости kotlin-maven-plugin и указать его в compilerPlugins:
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>1.8.0</version>
<configuration>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
<!--...-->
</plugin>
(Источник: https://www.baeldung.com/kotlin/jpa)
В Gradle:
plugins { id "org.jetbrains.kotlin.plugin.jpa" version "1.5.21" }
2. В Kotlin классы, свойства и методы по умолчанию final. Класс сущности не должен быть final. Никакие методы и атрибуты сущности не могут быть final, поэтому их нужно явно помечать ключевым словом open.
3. Реализации equals() и hashCode() должны учитывать мутабельность сущностей.
4. Как и в java, нужно учитывать работу с lazy коллекциями.
Для ID, генерируемый в БД следующее решение с @NAturalId:
@Table(name = "contact") @Entity data class Contact( @NaturalId @Column(name = "email", nullable = false, updatable = false) val email: String ) { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) var id: Long? = null // other properties omitted }
Так делать можно, но нужно ли? Такой подход сводит пользу от классов данных на нет, поскольку делает декомпозицию бесполезной и использует только одно поле в методе toString().
Итого: Обычный класс подойдет для сущностей лучше
.