How to customize the JSON Serializer used by Hibernate-Types

(Last Updated On: March 27, 2018)

Introduction

As already explained, the hibernate-types open-source project allows you to map JSON, ARRAY, PostgreSQL ENUM types and provides a simple way of adding immutable Hibernate Types.

After adding support for customizing the Jackson ObjectMapper, the next most-wanted issue was to provide a way to customize the JSON serializing mechanism.

In this article, you are going to see how you can customize the JSON serializer using hibernate-types.

Declarative configuration

The easiest way to achieve this goal is to set the hibernate.types.json.serializer configuration property in the hibernate.properties file:

hibernate.types.json.serializer=com.vladmihalcea.hibernate.type.json.configuration.CustomJsonSerializerSupplier

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

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

You can even supply a different Java properties file via the hibernate-types.properties.path System property,

The CustomJsonSerializerSupplier can look as follows:

public class CustomJsonSerializerSupplier 
    implements JsonSerializerSupplier {

    @Override
    public JsonSerializer get() {
        return new CustomJsonSerializer();
    }
}

Here, for testing sake, we are using a custom CustomJsonSerializer that implements the JsonSerializer interface:

public class CustomJsonSerializer 
    implements JsonSerializer {

    private static boolean called;

    public static boolean isCalled() {
        return called;
    }

    public static void reset() {
        called = false;
    }

    @Override
    public <T> T clone(T value) {
        called = true;
        return JacksonUtil.clone(value);
    }
}

We are going to use the called static variable to check in our unit test if this method is called by hibernate-types.

assertFalse(CustomJsonSerializer.isCalled());

doInJPA(entityManager -> {
    Location location = new Location();
    location.setCountry("Romania");
    location.setCity("Cluj-Napoca");
    location.setReference(
        BigDecimal.valueOf(2.25262562526626D)
    );

    Event event = new Event();
    event.setId(1L);
    event.setLocation(location);
    entityManager.persist(event);
});

assertTrue(CustomJsonSerializer.isCalled());
CustomJsonSerializer.reset();
assertFalse(CustomJsonSerializer.isCalled());

doInJPA(entityManager -> {
    Event event = entityManager.find(Event.class, 1L);
    assertEquals(
        "2.25262562526626", 
        event.getLocation().getReference().toString()
    );
});

assertTrue(CustomJsonSerializer.isCalled());

As you can see, the CustomJsonSerializer is being used, so you can easily customize the way a given JSON object is serialized by hibernate-types.

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

Conclusion

Because of the configuration mechanism, I introduced for customizing the ObjectMapper, it is very easy to add new configuration options, like this one which allows you to change the way a given JSON object is serialized by hibernate-types.

Subscribe to our Newsletter

* indicates required
10 000 readers have found this blog worth following!

If you subscribe to my newsletter, you'll get:
  • A free sample of my Video Course about running Integration tests at warp-speed using Docker and tmpfs
  • 3 chapters from my book, High-Performance Java Persistence, 
  • a 10% discount coupon for my book. 
Get the most out of your persistence layer!

Advertisements

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.