How can I generalize JsonConverter for all classes?

381 Views Asked by At

I have an entity like below:

@Entity
@Table(name = "orders")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Order {

    @Convert(converter = UserInfoJsonConverter.class)
    private UserInfo userInfo;

    @Convert(converter = IndUserInfoJsonConverter.class)
    private IndUserInfo indUserInfo;

    @Convert(converter = DuplicateInfoJsonConverter.class)
    private DuplicateInfo duplicateInfo;

    @Convert(converter = PartnershipJsonConverter.class)
    private PartnershipInfo partnerShipInfo;

    @Convert(converter = SecretJsonConverter.class)
    private SecretInfo secretInfo;
    
    ....

And as you see I have 5 fields as JSON string in DB. And also I have 5 JsonConverter implementations like below:

    @Slf4j
    @Converter(autoApply = true)
    public class IndUserInfoJsonConverter implements AttributeConverter<IndUserInfo, String> {

        private final ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public String convertToDatabaseColumn(IndUserInfo attribute) {
            try {
                objectMapper.registerModule(new JavaTimeModule());
                return objectMapper.writeValueAsString(attribute);
            } catch (JsonProcessingException ex) {
                log.error("Could not write view {} to json", attribute, ex);
                throw new InternalServerErrorException("Could not write the object details into string", ex);
            }
        }

        @Override
        public IndUserInfo convertToEntityAttribute(String dbData) {
            try {
                objectMapper.registerModule(new JavaTimeModule());
                return dbData == null ? null : objectMapper.readValue(dbData, IndUserInfo.class);
            } catch (JsonProcessingException ex) {
                log.error("Could not write view {} to json", dbData, ex);
                throw new InternalServerErrorException("Could not convert input string into object", ex);
            }
        }

    }

And my question is how can I generalize these implementations? I mean how can I get rid of code repeat? Because the only difference is IndUserInfo in here.

1

There are 1 best solutions below

0
Christian Beikov On

Since converters don't have access to the model type, you can't use this approach in a generic way. You could use a UserType which can inject the model type, but then you could also use the hibernate-types project for this purpose.

As of Hibernate 6, you don't need any of this, as it comes with JSON support out of the box. You just have to annotate the persistent attribute with @JdbcTypeCode(SqlTypes.JSON)