How to customize the Jackson ObjectMapper used by Hibernate-Types

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Hypersistence Optimizer is that tool!


As already explained, the hibernate-types open-source project allows you to map JSON, ARRAY when using JPA and Hibernate.

Since I launched this project, one of the most wanted feature was to add support for customizing the underlying Jackson ObjectMapper, and since version 2.1.1, this can be done either declaratively or programmatically.

In this article, you are going to see how do customize the ObjectMapper when using the hibernate-types project.

Declarative configuration

The easiest way to achieve this goal is to set the hibernate.types.jackson.object.mapper configuration property in the file:


This property takes the fully-qualified class name of an implementation of the ObjectMapperSupplier interface:

What’s nice about customizing the hibernate-types project is that you can use either the Hibernate-specific or you can provide a file if you cannot alter

You can even supply a different Java properties file via the System property.

The CustomObjectMapperSupplier can look as follows:

public class CustomObjectMapperSupplier 
    implements ObjectMapperSupplier {

    public ObjectMapper get() {
        ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();
        SimpleModule simpleModule = new SimpleModule(
            new Version(1, 0, 0, null, null, null)
        simpleModule.addSerializer(new MoneySerializer());
        return objectMapper;

Here, we are using a custom ObjectMapper that uses our own MoneySerializer for handling BigDecimal Java Object types:

public class MoneySerializer 
    extends JsonSerializer<BigDecimal> {

    public void serialize(
                BigDecimal value, 
                JsonGenerator jsonGenerator, 
                SerializerProvider provider)
            throws IOException {
            value.setScale(2, BigDecimal.ROUND_HALF_UP).toString()

    public Class<BigDecimal> handledType() {
        return BigDecimal.class;

So, if you are persisting the following Book entity which has a JSON properties attribute:

Book book = new Book();
        "{" +
        "   \"title\": \"High-Performance Java Persistence\"," +
        "   \"author\": \"Vlad Mihalcea\"," +
        "   \"publisher\": \"Amazon\"," +
        "   \"price\": 44.991234567" + 


When fetching the Book entity, we can see that the BigDecimal takes only two decimals:

Book book = entityManager


Programmatic configuration

For even more flexibility, you can use the programmatic configuration.

Assuming we have the following Object type that we want to serialize as JSON:

public class Location 
    implements Serializable {

    private String country;

    private String city;

    private BigDecimal reference;

    //Getters and setters omitted for brevity

And, we have an Event entity that maps the Location Java Object to a jsonb PostgreSQL column type:

@Entity(name = "Event")
@Table(name = "event")
public class Event {

    private Long id;

    @Type(type = "location")
    @Column(columnDefinition = "jsonb")
    private Location location;

    //Getters and setters omitted for brevity

We can use a custom ObjectMapper as follows:

JsonType jsonType = new JsonType(
    new CustomObjectMapperSupplier().get(), 

    (TypeContributorList) () -> Collections.singletonList(
        (typeContributions, serviceRegistry) ->
                jsonType, "location"

The hibernate.type_contributors configuration property allows you to register custom Hibernate Types, and we can use this feature to provide our own custom ObjectMapper to the JsonType provided by the hibernate-types project.

So, if we persist the following Event entity:

Location location = new Location();

Event event = new Event();


When fetching the Event entity, we can see that the BigDecimal takes only two decimals:

Event event = entityManager.find(Event.class, 1L);

assertEquals("2.25", event.getLocation().getReference().toString());

Cool, right?

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.

Seize the deal! 50% discount.


Not only that you can customize the ObjectMapper when using the hibernate-types project, but the new configuration mechanism will allow for customizing other behaviors as well.

So, stay tuned for more!

Transactions and Concurrency Control eBook

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

High-Performance Java Persistence 📚 - 50% OFF