2

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.

ElbrusGarayev
  • 91
  • 1
  • 1
  • 7
  • If possible make your entity classes to extend one class and write a converter class for that and check class type by using instance of and based on that call different methods for converting your data. Can you please try let me know if it worked on not. Thank you. – Praveen kumar Oct 08 '22 at 11:45

1 Answers1

0

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)

Christian Beikov
  • 15,141
  • 2
  • 32
  • 58