Java 测试时h2的json反序列化问题
我有下面的hibernate实体Java 测试时h2的json反序列化问题,java,json,h2,Java,Json,H2,我有下面的hibernate实体 @Data @Entity @TypeDef( typeClass = JsonStringType.class, defaultForType = MetaData.class ) public class DbEntity(){ @Column(name = "id", unique = true, nullable = false) private String id; @Column(name =
@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;
}
元数据类如下所示:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MetaData {
private Long amount;
private Date date;
}
元数据字段在数据库中存储为json。这适用于mysql。但我使用h2编写测试,无法读取字段元数据中的值
我得到的例外是:
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]
我正在使用h2的1.4.200
version
针对这个问题提到的大多数解决方案都是支持json或jsonb的h2。但我的h2版本支持json
另外,如果我从元数据的@Column
中删除columnDefinition=“json”
,测试将按预期工作。但是,在这种情况下,mysql实现不起作用
h2官方页面建议在insert sql语句中添加格式JSON
。但是我不知道如何添加它,因为我正在使用hibernate。如果您没有真正好的理由使用json列,只需更改@Column
中的decolumnDefinition
属性即可
@Column(name = "meta_data", columnDefinition = "text")
@Convert(converter = JsonConverter.class)
private MetaData metaData;
并定义自定义转换器:
@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);
}
}
@转换器
公共静态类JsonConverter实现AttributeConverter{
私有静态最终ObjectMapper mapper=新ObjectMapper();
@凌驾
@鬼鬼祟祟
公共字符串convertToDatabaseColumn(元数据){
返回mapper.writeValueAsString(元数据);
}
@凌驾
@鬼鬼祟祟
公共元数据convertToEntityAttribute(字符串s){
返回mapper.readValue(s,MetaData.class);
}
}