Frank
Frank

Reputation: 12300

Realm and Retrofit2: sending auto-managed objects

When using Realm and Retrofit2 for sending auto-managed RealmObjects to our server, Retrofit2 (using Gson) only sends the ints in the RealmObject. It completely ignores the Strings and other fields, and does not put these in the json. No errors are logged.

If I however, disconnect the RealmObject from Realm:

realm.copyFromRealm(myRealmObject)

then it does send all fields. What could be the problem? Is there a proper solution?

Upvotes: 4

Views: 543

Answers (2)

Before we dive in

In one of my posts here on Stackoverflow, I have explained what's happening when using Gson and Realm together (Retrofit is just using Gson as a data converter, so it's Gson that's failing not Retrofit). The link is posted down below.

Let's dive in

... only sends the ints in the RealmObject

Nope! Not just ints...

If you look closely, you'll notice that even your ints are set to 0 (which is the null value for an int). The same thing would happen with a boolean, you would get false in the serialized output.

In fact, all your RealmObject attributes are set to null when this same realmObject is managed. When you try to read/write an attribute (from a managed realmObject), Realm will read/write its value from/to the persistence layer (using proxies) so you're sure you're getting/setting the right value of this realmObject (not just getting an old value from the memory).

That being said, I can now explain why Gson is only serializing ints.

  • When your attribute is an object, its value will be equal to null (a reference pointing to nowhere) and Gson won't bother serializing it (you won't see it in the output).

  • When your attribute is a scaler type (char, int, boolean, float ...) its value will be equal to whatever corresponds to a null (every bit in the scalar is 0) and Gson will serialize it cause it's considered to be a valid value. This explains "why only your ints are serialized".

If I however, disconnect the RealmObject from Realm ... then it does send all fields.

When your realmObject is unmanaged it'll act a normal java object (no proxies are used to maintain the coherence between the object in memory and the persisted one) and of course Gson will have no trouble serializing it.

Is there a proper solution?

There are workarounds. In the post I mentioned earlier, I tried to gather some recommended ones (IMO) to deal this incompatibility. Here's the link: "Android: Realm + Retrofit 2 + GSON".

Upvotes: 5

RoShan Shan
RoShan Shan

Reputation: 2954

Your code realm.copyFromRealm(myRealmObject) change a RealmObject to a normal object (POJO), said by document Makes an unmanaged in-memory copy of an already persisted RealmObject (although you can define depth parameter.)

With Retrofit2, now only support normal object, I think your codes are absolutely correct, but GSON reads field values for serialization, and managed Realm proxies have all null fields (read here).

Change RealmObject to normal Java object using realm.copyFromRealm() and send it to server.

Upvotes: 0

Related Questions