Categories: Java, JPA

Persisting enums using JPA attribute converter

persisting enums using jpa attribute converterBefore the JPA 2.1 specification be released in 2013 the simple task to persist and load enums could be performed but not in a simple and decent way. In this article I’m going to present you some old techniques to solve this problem and how the new JPA specification established an appropriate way for persisting enums using JPA attribute converter.

To access the complete JSR 338: Java Persistent 2.1 specification, please follow this link: https://jcp.org/en/jsr/detail?id=338.

Back in the old days (before the JPA 2.1)

The Enumerated techinique

One of the most spreaded solutions for the enums’ persistence problem was the Enumerated technique. It consists in the usage of the Enumerated annotation with EnumType.ORDINAL or EnumType.STRING. I personally don’t like this approach because when we use the EnumType.ORDINAL it assumes the position of the items will never change inside the enum and when using EnumType.STRING we will persist the same string repeated times in the DB.

Example:

Custom hibernate annotations

This is a very verbose and hibernate-specific solution. The idea is basically implement a new class that implements an hibernate custom type and then annotate your enum attribute using it. You can see a good implementation example here.

Example:

What I really dislike on this approach is that it’s really attached to the hibernate’s implementation and not to the JPA specification.

@PrePersist and @PostLoad trick

This solution works and is kind of simple to implement but it’s really dirty. Here the main idea is to have two attributes, the first one is an integer attribute (the one that will really be persisted in the DB) and the other one is as enum attribute (that must be used while coding). The two attributes are synchronized every time the entity is persisted (using the @PrePersist callback) or the entity is loaded (using the @PostLoad callback). As you could see the alternatives to implement a persistent enum attribute were either complex or error-prone, and in some case both.

The JPA Attribute converter

Introduced by the JPA 2.1 specification the Attribute converter is a very simple and handy way to convert any basic attribute (not only enums) to a specific database representation.

From the JSR 338: Java Persistent 2.1 specification:

The attribute conversion facility allows the developer to specify methods to convert between the entity attribute representation and the database representation for attributes of basic types. Converters can be used to convert basic attributes defined by entity classes, mapped superclasses, or embeddable classes.

An attribute converter must implement the javax.persistence.AttributeConverter interface. A converter implementation class must be annotated with the Converter annotation OR defined in the XML descriptor as a converter. If the value of the autoApply element of the Converter annotation is true, the converter will be applied to all attributes of the target type, including to basic attribute values that are contained within other, more complex attribute types.

Let’s implement a simple scenario to demonstrate this new feature from JPA.

Imagine we have the following enum “PaymentType” containing the items credit card, debit card and money.

As you could see above, each enum item has a respective ID value assigned to it (10, 20 and 30). Now, we will implement an attribute converter responsible for telling JPA how to convert the enum item to its respective DB value and vice versa.

Once we have the enum and attribute converter classes in place the last step is just use them 🙂

It’s pretty straightforward and intuitive. Check it out:

Conclusion

The Attribute converter is very useful when you want to use an enum within a JPA entity. It will enable you to have a transparent conversion between you enum items and their respective database values. The result is a much more clean code. No more dependencies on the enum items’ positions or tricks.

Article info