Solution 1:

Why writing all these custom serializers when you can make Gson and Realm work together with just ONE LINE OF CODE?

IMO, setting an exclusive strategy to every model we want to serialize is not the best approach. As you have realized, this approach requires writing a lot of boiler-plate code which is error prone and the worst of all, kills what Gson is about (which is making our lives less painful).

And since we're working-around incompatibilities, why don't you just make sure to pass an unmanged RealmObject to your Gson serializer?

Simplest solution ever (IMO)

Found here. Get a copy in memory of the managed RealmObject and pass it to Gson

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

And that's it! No more code to write!

Other good solutions and explanations are posted here.

Solution 2:

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