У меня есть столбец в БД, я хочу сохранить его как JSON и получить обратно.
Мой подход:
Я сохраняю его как ClobTypeHandler и пытаюсь восстановить как ClobTypeHandler.
Я использую Mybatis, но получаю ошибку ниже.
Could not set property 'idType' of 'class package.abc' with value '{"idNum":"123","text":"ENCkk-KZJTmN8Mr5jEims0rssRow8xaAnkOtl0RQHDth1ByVtshI7zQebtcogOvYM-gNo15DwwPmduaufk03CteqRL03cRyrG4%3B","key":"}P]H73}AF}TGB$OIDCYVIIB+VW{4TR)I?U}_`_ZXP[UY$BJNXV{U~/@!F%+SVMFYT/2IAXIOPB"}' Cause: java.lang.IllegalArgumentException: argument type mismatch
Ниже показан уровень Java и детали БД.
class abc{
private JsonNode idType;
public String getIdType() {
return idType != null ? idType.toString():null;
}
public void setIdType(JsonNode idType) {
this.idType = idType;
}
}
mapper.xml (вставка в БД)
INSERT INTO CUSTOMER
(<include refid = "common_customer_insert_columns"></include>,id_type)
VALUES
(<include refid = "common_customer_insert_fields"></include>,<include refid = "cc_customer_insert_fields"></include>,
<choose> <when test = "abc.idType !=null">#{abc.idType,typeHandler= org.apache.ibatis.type.ClobTypeHandler}</when>
<otherwise>''</otherwise></choose>);
mapper.xml (при чтении из БД)
<resultMap>
<result column = "id_type" property = "abc.idType"
typeHandler = "org.apache.ibatis.type.ClobTypeHandler" />
</resultMap>
образец значения JSON, который я пытаюсь сохранить и получить:
"idType": {
"idNum": "123",
"text": "ENh-KZJTmN8Mr5jEims0rssRow8xaADth1ByVtshI7zQebtcogOvYM-gNo15DwwPmduaufk03CteqRLaVwF0b3cRyrG4%3D",
"key":"}P]H73}AF}TGB$OICQ*DCYVIIB+VW{4TR)I?U}_`_ZXP[UY$BJNXV{@!F%+SVMFYT/2IAXIOPB"
}




Вы можете сделать это без использования POJO:
ObjectMapper mapper = new ObjectMapper();
JsonNode idType = mapper.readTree(<json-string>);
да, но мне нужен POJO, так как есть дополнительные поля, которые POJO состоит вместе с этим полем
ClobTypeHandler расширяет BaseTypeHandler<String>, так что он позволяет устанавливать и извлекать значение из столбца базы данных как String. Когда вы используете ClobTypeHandler вот так:
#{abc.idType,typeHandler= org.apache.ibatis.type.ClobTypeHandler}
mybatis под капотом ожидает, что abc.getIdType вернет String, что он и делает. Все идет нормально.
Когда вы извлекаете значение из базы данных, используется сопоставление:
<result column = "id_type" property = "abc.idType"
typeHandler = "org.apache.ibatis.type.ClobTypeHandler" />
В этом случае ClobTypeHandler пытается установить свойство idType с помощью установщика setIdType и ожидает, что он примет String. Но аргумент установщика - JsonNode, поэтому вы получите сообщение о несовместимости типа.
Чтобы исправить это изменение, установщик типов получает и выполняет в нем преобразование из String в JsonNode:
public void setIdType(String idTypeString) {
ObjectMapper mapper = new ObjectMapper();
this.idType = mapper.readTree(isTypeString);
}
Примечание: вы можешь использовать static ObjectMapper, чтобы избежать его создания при каждом вызове.
Лучше создать твой собственныйTypeHandler для типа JsonNode. Он будет выполнять преобразование String <=> JsonNode внутренне, чтобы ваш abc не был загрязнен этой (несвязанной) логикой.
После изменения метода установки с помощью objectMapper я получаю следующую ошибку: - package.abc ["idType"]) "error = " com.fasterxml.jackson.databind.JsonMappingException - Невозможно десериализовать экземпляр java.lang.String вне Токен START_OBJECT
любое обновление по этому поводу, сталкивающееся с той же проблемой