I want to make a AttributeConverter which map object to json string.Simply I write it like:
// 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);
}
}
It won't work correctly since the field's generic information lost on deserialization.If I can get field which the @Convert is annotating with,then I can make it right by add some code in function convertToEntityAttribute
:
public Object convertToEntityAttribute(String dbData) {
Type genericType = field.getGenericType();
JavaType javaType = JsonUtil.getTypeFactory().constructType(genericType);
return JsonUtil.string2Object(dbData, javaType);
}
I impletemented this requirement by extending hibernate UserType, but I am wondering how to make it in AttributeConverter.Here is what that look like:
@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);
}
Btw it is possible to make it like what they do in this question: Is it possible to write a generic enum converter for JPA?
It is not convenient since I have to transfer the field's generic information by myself. And when it is a Map,I have to extends a Map to transfer generic information.