6 Gotchas of Hibernate You Wish You Knew Earlier

This post is about the confusions of a programmer familiar with many other ORMs was asked to use Hibernate for the first time.

An offline database — file archive
Photo by Twitter: @jankolario on Unsplash

You need a private/protected default constructor

Hibernate uses reflection to read and write classes to and from database rows. It uses proxy classes to facilitate lazy loading. For this, it needs to instantiate the class using a parameter-less constructor which must be protected or private. Without a parameterless constructor, you will meet a weird error message. IDEA has a warning, if enabled, will help you prevent these mistakes.

Quoting table names

Create an Entity called User, connect it with a Spring DaoUserDetailsProvider watch the world burn.

You have to create your own migrations

Java has tools that will help you to run migrations but you must author them yourself. While I believe this is the safest approach as framework generated code may be sub-optimal, devoid of aesthetics and sometimes outright wrong (more on this later). If you have a dozen of new entities with dozen of new fields, authoring migrations manually quickly becomes a hassle.

spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=src/main/resources/db/migrations/schema.sql
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=update

Understand how two-way relationships behave

If you are using a bidirectional one-to-many/many-to-one relationship to model your data, you must be careful. A bi-directional relationship is traditionally modeled as a field on the one-to-many side — called the owning side. The model with many-to-one relationship is called inverse-side. However, the database only stores data at one of the sides and the other side is populated by the ORM layer. Making changes on the owning side will not automatically make changes in the inverse side until you flush the data.

Database ID generation is different

Hibernate uses its own ID generator by default which uses a value from a table and computes IDs for each entity you insert. This means that your ID ranges will not be sequential or continuous. This is not an issue that affect applications (I use a UUID anyway), but is surprising. You can make hibernate to use your database’s native method of generating IDs though by specifying a different GenerationStrategy.

Automatic code-generation for JPA repositories

For JPA repositories, Hibernate can automatically generate SQL for you just from the function name and type parameters.

Computer Whisperer. Open-source contributor. Find me at https://amitosh.in/