Home United States USA — software Best Practices of Using JPA (Hibernate) With Kotlin

Best Practices of Using JPA (Hibernate) With Kotlin

297
0
SHARE

Defining JPA entities in Kotlin comes with some caveats. Let’s look at how to avoid the common pitfalls and make the most of using Kotlin.
Join the DZone community and get the full member experience. There is no JPA without entities, and defining them in Kotlin comes with some caveats. Let’s look at how to avoid the common pitfalls and make the most of using Kotlin. Spoiler alert: data classes are not the best option for entity classes. This article will be mostly focused on Hibernate as it is undoubtedly the leader among all JPA implementations. Entities are not regular DTOs. To work, and work well, they need to satisfy certain requirements, so let’s start by defining them. The JPA Specification provides its own set of restrictions, and here are the two most important to us: These requirements are enough to make entities work, but we need additional rules to make them work well: Primary constructors are one of the most loved features in Kotlin. However, adding a primary constructor we lose the default one, so if you try to use it with Hibernate, you get the following exception: org.hibernate. InstantiationException: No default constructor for entity. To resolve this issue, you may manually define a no-args constructor in all entities. Alternatively, and preferably, use the kotlin-jpa compiler plugin which ensures that no-args constructor is generated in the bytecode for each JPA-related class: @Entity, @MappedSuperclass or @Embeddable. To enable the plugin, simply add it to the dependencies of kotlin-maven-plugin and to compilerPlugins: In Gradle: As per the JPA specification, all JPA-related classes and properties must be open. Some JPA providers don’t enforce this rule. For example, Hibernate does not throw an exception when it encounters a final entity class. However, a final class cannot be subclassed, hence the proxying mechanism of Hibernate turns off. No proxies and no lazy loading. Effectively, this means that all ToOne associations will be always eagerly fetched. This can lead to significant performance issues. The situation is different for EclipseLink with static weaving, as it doesn’t use subclassing for its lazy loading mechanism.

Continue reading...