6

私はjsonフィールドで持っています_id

 String json = "{ _id : 1, name : 'Alex', role: 'admin' }"

私の Realm モデルでは、次の@SerializedName属性を使用します。

public class User extends RealmObject {

    @SerializedName("_id")  
    @PrimaryKey
    private int id;
    private String name;
    private String comment;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

}  

json を保存しようとすると、次のようになります。

realm.createOrUpdateObjectFromJson(User.class, json)

フィールド_idを解析できず、データベースで ID = 0 のレコードが作成されました

@SerializedName属性を使用したドキュメント

  Gson gson = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            }).create();


User user = gson.fromJson(json, User.class);
realm.beginTransaction();
realm.copyToRealmOrUpdate(user);

この場合、String のデフォルト値は null であるため、データベースからjson = "{ _id : 1, role: 'user' }"ユーザーを削除するだけです。name

したがって、おそらく私は属性を間違って使用しています。createOrUpdateObjectFromJsonjson の保存方法 (など)を扱うときに属性を考慮する方法は?

4

2 に答える 2

15

わずか1 行のコードでGsonRealmを連携させることができるのに、これらすべてのカスタムシリアライザーを作成する必要はありません。

IMO、シリアライズしたいすべてのモデルに排他的な戦略を設定することは、最善のアプローチではありません. お気付きのように、このアプローチでは多くのボイラープレート コードを記述する必要があり、エラーが発生しやすく、最悪の場合、Gsonの機能が失われます(これにより、私たちの生活の苦痛が軽減されます)。

また、非互換性に対処しているので、管理されていないRealmObjectGsonシリアライザーに渡すようにしてください。

これまでで最も簡単なソリューション (IMO)

ここにあります。管理された RealmObject のメモリ内のコピーを取得し、それをGsonに渡します

new Gson().toJson(realm.copyFromRealm(managedModel));

以上です!コードを書く必要はもうありません。

他の良い解決策と説明がここに掲載されています。

于 2017-02-04T19:21:06.497 に答える
4

You probably need a hybrid solution in order to make this work. The reason is that @SerializedName is a GSON annotation and not one that Realm knows about. So this means you have two choices as you already discovered:

1) Use GSON, which means the end result is an object with null as the default for name.

2) Use createOrUpdateObjectFromJson which means that _id will be ignored because Realm's JSON parser require a 1:1 mapping.

As neither solution will work correctly you can modify them in the following way:

1) With GSON, instead of doing copyToRealmOrUpdate you can manually search for the object and update the role:

realm.beginTransaction();
realm.where(User.class).equalTo("id", user.getId()).findFirst().setRole(user.getRole());
realm.commitTransaction();

2) Using just the pure JSON you can modify to match the expected format:

JSONObject obj = new JSONObject(json);
obj.put("id", obj.getString("_id"));
obj.remove("_id");

Realm has an issue tracking the request for custom mappings, but it has a low priority as that feature is usually better covered by frameworks such as GSON, Jacokson, etc. : https://github.com/realm/realm-java/issues/1470

于 2016-02-10T10:23:03.160 に答える