我想制作一个AttributeConverter,将对象映射到json字符串。简单地说,它是这样写的:
// JsonUtil wrap jackson's mapper simply
@Converter
public class JsonConverter implements AttributeConverter<Object,String> {
@Override
public String convertToDatabaseColumn(Object attribute) {
if (attribute == null) {
return null;
}
return JsonUtil.object2String(attribute);
}
@Override
public Object convertToEntityAttribute(String dbData) {
return JsonUtil.string2Object(dbData, Object.class);
}
}
由于反序列化会丢失字段的通用信息,因此无法正常工作。如果我可以获取@Convert注释的字段,则可以通过在函数convertToEntityAttribute
中添加一些代码来使其正确:< / p>
public Object convertToEntityAttribute(String dbData) {
Type genericType = field.getGenericType();
JavaType javaType = JsonUtil.getTypeFactory().constructType(genericType);
return JsonUtil.string2Object(dbData, javaType);
}
我通过扩展休眠的UserType满足了这一要求,但我想知道如何在AttributeConverter中实现它。这是这样的:
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
String json = rs.getString(names[0]);
if (StringUtils.isEmpty(json)){
return null;
}
String columnName = rs.getMetaData().getColumnName(rs.findColumn(names[0]));
Field field;
try {
field = owner.getClass().getDeclaredField(columnName);
} catch (NoSuchFieldException e) {
throw new RuntimeException(String.format("反序列化时发现实体类[%s]中不存在字段名为[%s]的字段",owner.getClass().getSimpleName(),columnName),e);
}
Type genericType = field.getGenericType();
JavaType javaType = JsonUtil.getTypeFactory().constructType(genericType);
return JsonUtil.string2Object(json, javaType);
}
顺便说一句,有可能像他们在这个问题上所做的那样: Is it possible to write a generic enum converter for JPA?
这不方便,因为我必须自己传输该字段的一般信息。当它是Map时,我必须扩展Map才能传输通用信息。