I have json
with field _id
String json = "{ _id : 1, name : 'Alex', role: 'admin' }"
In my Realm model I use @SerializedName
attribute:
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;
}
}
If try save the json:
realm.createOrUpdateObjectFromJson(User.class, json)
field _id
can't parsed and in database created record with id = 0
In docs using @SerializedName
attribute
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);
In this case json = "{ _id : 1, role: 'user' }"
just remove user name
from database, because default value for String is null.
So, probably I incorrectly using the attribute. How to consider the attribute when dealing with the methods of conservation of json (createOrUpdateObjectFromJson
, etc)?
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