Не удается сохранить нулевое значение столбца в ActiveAndroid
Для простоты у меня есть эта модель:
@Table(name = "Items")
class TItem extends Model {
@Column(name = "title")
private String mTitle;
public String getTitle() { return mTitle; }
public void setTitle(String title) { mTitle = title; }
}
И я проваливаю тесты:
//Create new object and save it to DDBB
TItem r = new TItem();
r.save();
TItem saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = null --> OK
r.setTitle("Hello");
r.save();
saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = "Hello" --> OK
r.setTitle(null);
r.save();
saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = "Hello" --> FAIL
Кажется, я не могу изменить значение столбца с нуля в ActiveAndroid. Очень странно. Это ошибка? Я ничего не нашел об этом, но выглядит довольно просто в этой функциональности.
Если я отлаживаю приложение и следую методу сохранения, последняя полученная команда находится в SQLLiteConnection.java:
private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
....
// It seems ok, as it is really inserting a null value in the DDBB
case Cursor.FIELD_TYPE_NULL:
nativeBindNull(mConnectionPtr, statementPtr, i + 1);
....
}
Я не могу видеть дальше, так как "nativeBindNull" не доступен
2 ответа
Наконец-то я выяснил, что произошло, и проблема в библиотеке ActiveAndroid.
Значение NULL правильно сохранено в DDBB, но не получено правильно. Поскольку ActiveAndroid использует кэшированные элементы, при получении элемента он получает "старую версию" и обновляет ее новыми значениями. Здесь библиотека терпит неудачу, потому что проверяет, что если не пусто, замените значение, иначе ничего.
Чтобы решить эту проблему, мы должны изменить его из библиотеки в классе Model.java:
public final void loadFromCursor(Cursor cursor) {
List<String> columnsOrdered = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));
for (Field field : mTableInfo.getFields()) {
final String fieldName = mTableInfo.getColumnName(field);
Class<?> fieldType = field.getType();
final int columnIndex = columnsOrdered.indexOf(fieldName);
....
if (columnIsNull) {
<strike>field = null;</strike> //Don't put the field to null, otherwise we won't be able to change its content
value = null;
}
....
<strike>if (value != null)</strike> { //Remove this check, to always set the value
field.set(this, value);
}
....
}
....
}
Вы можете сохранить поле\поля по объекту Update:
Update(YourModelClass::class.java)
.set("field_one = ${value1}, field_second = $value2")
.where("id = ?", model.id)
.execute()
Если вы добавите кавычки, значения будут сохранены в виде текста:
Update(YourModelClass::class.java)
.set("field_one = '$value1', field_second = '$value2'")
.where("id = ?", model.id)
.execute()