1

簡単にするために、次のモデルがあります。

@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 では、列の値を何かから null に変更できないようです。非常に奇妙な。バグですか?私はそれについて何も見つけませんでしたが、この機能はかなり基本的です。

アプリをデバッグして保存方法に従うと、到達する最後のコマンドは 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」が利用できないため、これ以上見ることができません

4

1 に答える 1

3

最後に、何が起こったのかを見つけました。問題は ActiveAndroid ライブラリにあります。

null 値は DDBB に適切に保存されますが、正しく取得されません。ActiveAndroid はキャッシュされたアイテムを使用するため、要素を取得するときに「古いバージョン」を取得し、新しい値で更新します。null でない場合は値を置き換え、それ以外の場合は何もしないことをチェックしているため、ここでライブラリが失敗します。

これを解決するには、クラス 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);
        }
        ....
    }
    ....
}
于 2015-05-18T17:25:08.460 に答える