Implementing an AttributeConverter with JPA

Implementing an AttributeConverter With JPA

All JPA implementations, including Hibernate, provide default mappings for a large set of standard Java classes. Through these mappings it is possible to model the attributes of an entity and map a table.
But sometimes this is not possible, for this reason in this article we’ll see how to implement an AttributeConverter with JPA.

Diagram

Our application uses the following table called country which has two properties, name and code. The latter serves to identify a country and is unique.

Implementing an AttributeConverter with JPA

Now let’s proceed with the mapping by creating the following classes:

@Entity
@Table(name = "country")
public class Country {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	private String name;

	private CountryCode code;
	
	// getters and setters

}
public enum CountryCode {
	
	ITALY("ita");

	private String value;
	
	// constructor and getter
	
}

The Country entity uses an enumerate to save the code. Now we need a converter that transforms CountryCode into a database column and vice versa. In our case we will save the value property of CountryCode in the database and instead when we read we will convert the string into CountryCode.

To do this we need a converter and fortunately JPA provides us with an interface called AttributeConverter to implement.

Implementing an AttributeConverter

The JPA AttributeConverter is a great solution when you need to convert a particular Java type into a database column. Now let’s create our converter:

public class CountryCodeAttributeConverter implements AttributeConverter<CountryCode, String> {

	@Override
	public String convertToDatabaseColumn(CountryCode attribute) {
		return attribute.getValue();
	}

	@Override
	public CountryCode convertToEntityAttribute(String dbData) {
		return CountryCode.valueOf(dbData);
	}

}

The implementation of the AttributeConverter is pretty simple. The interface defines the methods convertToDatabaseColumn and convertToEntityAttribute. The JPA provider call these methods to either convert the value of your entity attribute to the type handled by the JDBC driver or vice versa.

Mapping the AttributeConverter

To inform JPA that we want to use a particular converter, we need to add the @Convert annotation on the attribute to be transformed. This is the classic approach if you intend to use the converter only in one entity.

@Convert(converter = CountryCodeAttributeConverter.class)
private CountryCode code;

Auto-registering the AttributeConverter

If you have multiple entities that use the same Java type that you set in the AttributeConverter, you can automatically register the converter by adding the @Converter annotation on the AttributeConverter implementation.

@Converter(autoApply = true)
public class CountryCodeAttributeConverter implements AttributeConverter<CountryCode, String> {

	//..

}

Using the AttributeConverter

Now that we have everything set up it’s time to try out our converter, let’s try inserting a Country:

EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("default");
EntityManager em = emFactory.createEntityManager();
em.getTransaction().begin();
Country country = new Country();
country.setName("Italy");
country.setCode(CountryCode.ITALY);
em.persist(country);
em.getTransaction().commit();
em.close();
emFactory.close();

For this project I used Hibernate as JPA implementation, below you’ll see the SQL it generated:

insert into country (id, code, name) values (default, 'ita', 'Italy')

Conclusion

In this article we have seen how you can implement an AttributeConverter with JPA. It provides an easy and portable way to define a custom mapping. You can use it for any attributes you want to map to a database column.
Source code is available on GitHub.

Lorenzo Miscoli

Software Developer specialized in creating and designing web applications. I have always loved technology and dreamed of working in the IT world, to make full use of my creativity and realize my ideas.
Scroll to Top