I have the following hibernate entity
@Data
@Entity
@TypeDef(
typeClass = JsonStringType.class,
defaultForType = MetaData.class
)
public class DbEntity(){
@Column(name = "id", unique = true, nullable = false)
private String id;
@Column(name = "user_id", nullable = false, updatable = false)
private String userId;
@Column(name = "meta_data", columnDefinition = "json")
private MetaData metaData;
}
The MetaData class is as follows:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MetaData {
private Long amount;
private Date date;
}
The metadata field is stored as json in db. This works with mysql. But I'm writing tests using h2 and am not able to read values in field metaData.
Exception I'm getting is:
Exception: The given string value: "{\"amount\":100,\"date\":1593690610000}" cannot be transformed to Json object
..
..
Caused by: java.lang.IllegalArgumentException: The given string value: "{\"amount\":100,\"date\":1593690610000}" cannot be transformed to Json object
..
..
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `foo.bar.MetaData` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{\"amount\":100,\"date\":1593690610000}')
at [Source: (String)""{\"amount\":100,\"date\":1593690610000}""; line: 1, column: 1]
I'm using 1.4.200 version of h2.
Most of the solutions mentioned for the problem are around h2 supporting json or jsonb. But my version of h2 supports json.
Also, if I remove columnDefinition = "json" from @Column of metaData, tests work as expected. But, in that case, mysql implementation doesn't work.
This h2 official page suggests to add FORMAT JSON in insert sql statement. But I'm not sure how to add it as I'm using hibernate.
If you don't have a really good reason to use json columns, just change de columnDefinition attribute in @Column
@Column(name = "meta_data", columnDefinition = "text")
@Convert(converter = JsonConverter.class)
private MetaData metaData;
And define a custom converter:
@Converter
public static class JsonConverter implements AttributeConverter<MetaData, String> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
@SneakyThrows
public String convertToDatabaseColumn(MetaData metaData) {
return mapper.writeValueAsString(metaData);
}
@Override
@SneakyThrows
public MetaData convertToEntityAttribute(String s) {
return mapper.readValue(s, MetaData.class);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With