Можно ли получить поле, которое @Convert аннотирует в jpa AttributeConverter? - PullRequest
0 голосов
/ 18 января 2019

Я хочу создать 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:

public Object convertToEntityAttribute(String dbData) {
    Type genericType = field.getGenericType();
    JavaType javaType = JsonUtil.getTypeFactory().constructType(genericType);
    return JsonUtil.string2Object(dbData, javaType);
}

Я реализовал это требование, расширив hibernate 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);
    }

Кстати, это можно сделать так, как они делают в этом вопросе: Можно ли написать общий преобразователь перечисления для JPA?

Это не удобно, так как я должен сам передать общую информацию поля. И когда это Карта, мне нужно расширить Карту для передачи общей информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...