The error

In this post, we will explore a very common Hibernate error, namely a MappingException caused by missing annotations on the Entity getters and fields.

Let us check the following stack trace as an example:

 

 

In the next section, we will display the faulty implementation that caused the error above. If you would like to skip to the solution, then please use the table of contents on the top of this post.

 

The example implementation

 

Now let us take a look at the code. The implementation contains two entities. The first entity is the bank account entity. The second entity is the transaction entity. Each bank account has two many-to-one relationships with the transaction table. A bank account has a list of transactions where it is credited, and a list of transactions where it its debited.

 

 

 

The problem cause

Sadly the information in the stacktrace is not very straightforward. It is telling us that the mapping between the Bank account and the Transaction table for the “credit_transactions” relationship is not correct. Hibernate does not understand the “credit_transactions” field.

 

The issue is that we have added annotations in the BankAccount entity on the fields and the getters. Notice that we added the @Id and @GeneratedValue annotations on the id field in the BankAccount entity. However, we added the @ManyToOne annotation for our relationship on the getters. If we add the @Id annotation on the getter and the @ManyToOne annotation on the field, then we will get the same error. This means that hibernate will consider only the annotations that are set on the same side as the @Id annotation. So if you add the @Id annotation on a field, then only field annotations will be considered. If the @Id annotation is set on the getter, then only annotations on the getters will be considered.

 

Adding the annotations on the entity fields is called “Field” access type. Adding the annotations on the entity getters is called “Property” access type. You can override JPA’s default behavior by setting the access type property of the entity.

 

 

Solution A

 

There are two ways to fix such an issue.  First, you will need to have the annotations on either the getters or the fields, but not both.  So, our bank account class would look as follows:

 

Solution B

 

While unlikely, it may sometimes be not possible to have the annotations on just one side. For example, if your entity is inheriting from a super class. In this case, you will have to override the annotations of the super class and specifically set the access type depending on which annotations we want to be effective. Let’s say that the superclass uses “field” annotations. Then we can write getters for the fields in the super and subclass and set the access type to “Property”:

 

If you would like to have a solid knowledge foundation about JPA and Hibernate, then I strongly recommend reading the book “High-Performance Java Persistence” by Vlad Mihalcea. The book focuses on JPA and working with relational databases in order to cleanly develop applications that utilize a persistence backend. The author is one of the developers of the Hibernate framework which gives it a high authority on the topic.

You can check more details about the book, how other users rate the book and the price from our Amazon affiliate link (redirects to your local Amazon store): “High-Performance Java Persistence