Home > OS >  Spring JPA custom serializer/deserializer
Spring JPA custom serializer/deserializer

Time:07-22

I'm using Spring Data Jpa Repositories with Hibernate and I'd like to add a custom serializer/deserializer that would be called whenever I call JpaRepository methods.

Idea is, I have an annotation @Encrypted, and when I save an Entity with a property annotated like this, I'd like to encrypt the property value and send it to DB encrypted. Then, whenever I select such entity, the property value will be decrypted accordingly. (I have done this for client-server communication already.)

How do I force the Spring JPA to serialize using my ObjectMapper?

I'm aware of @JsonSerialize(using=XYZSerializer.class), but that looks like a lot of redundant code(copy-pasting the same @JsonSerialize, @JsonDeserialize all over the place).


edit: I am currently using this code for client-server serialization. Would like to use the same for server-database

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JsonEncryptionConfig {
    
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();

        ClientServerEncryptionService clientServerEncryptionService = new ClientServerEncryptionService(mapper);
        DbEncryptionService serverDbEncryptionService = new DbEncryptionService(mapper);

        SimpleModule cryptoModule = new SimpleModule() {
            @Override
            public void setupModule(SetupContext context) {
                context.addBeanSerializerModifier(new EncryptedJsonSerializer.Modifier(clientServerEncryptionService, serverDbEncryptionService));
                context.addBeanDeserializerModifier(new EncryptedJsonDeserializer.Modifier(clientServerEncryptionService, serverDbEncryptionService));
            }
        };

        mapper.registerModule(cryptoModule);

        return mapper;
    }

}

CodePudding user response:

You can do that with an Entity Listener or a Hibernate Interceptor

Please checkout the docs how you can take part of the various events: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#events-jpa-callbacks

CodePudding user response:

Solution: you can't use serialization/deserialization to change data before SQL query is made. Instead, I followed this blog post: http://anshuiitk.blogspot.com/2010/11/hibernate-pre-database-opertaion-event.html and implemented a PreInsertEventListener, PreUpdateEventListener, PostLoadEventListener and as per the blog post, update not only the event.entity, but also event.state.

  • Related