Storing null values in realm using Android - android

Previously, when there was no stable version of realm for Java (Android), we could not store null values in realm and we had to perform some unnatural hack to be able to do so, as explained in this post.
But as of now realm 1.0 is released, are there any update about being able to store null value?
For example : unfortunate cases when there is no field in JSON which I want to store in realm after parsing but haven't handled it manually.
I have the following code:
realmObject.setData(jsonObject.getString("SELECTOR"));
the program flow stops and exits the block the code is located inside.
the logcat shows
W/System.err: org.json.JSONException: No value for SELECTOR
But when I do:
realmObject.setData(null);
The program flow does not stop and continues across my realm statement realmObject.setData(null);
In some cases, there is no value for the tag "SELECTOR" in my Json file.
And I want it to be null in default.

I actually found out that the problem is actually with just :
jsonObject.getString("SELECTOR")
not the whole statement:
realmObject.setData(jsonObject.getString("SELECTOR"));
so the fix for me was
realmObject.setData(jsonObject.optString("SELECTOR"));

you can use has that will check whether key is available of not and basis of that save value to realm object
if (jsonObject.has("SELECTOR")) {
realmObject.setData(jsonObject.getString("SELECTOR"));
}
else{
realmObject.setData(null);
}

Related

Cant retrieve data correctly from realm [duplicate]

This question already has answers here:
Cannot retrieve field values from realm object, values are null in debugger
(5 answers)
Closed 5 years ago.
I am trying to implement a generic realm wrapper. So, i can pass an object with its class to either add/update or get. I am using the realm browser to confirm that i am saving the data correctly, but when i perform a getAll query, i receive an array with the correct amount with the correct data structure but all the fields are in default values or null.
Here is my code :
Add RealmModel: (UserRealmModel)
#Override
public void putAll(Collection<RealmObject> realmModels) {
mRealm = Realm.getDefaultInstance();
mRealm.beginTransaction();
mRealm.copyToRealmOrUpdate(realmModels);
mRealm.commitTransaction();
}
GetAllRealmModels: (UserRealmModel)
#Override
public RealmResults getAll(Class clazz) {
return Realm.getDefaultInstance().allObjects(clazz);
}
I also tried:
#Override
public RealmResults getAll(Class clazz) {
return Realm.getDefaultInstance().where(clazz).findAll();
}
clazz = UserRealmModel.class
Output:
But whats interesting that in the debug view as shown in the screenshot, the toString method shows the correct data!
Help please :)
Mr Zeyad,
I went through Realm documentation for you. They have a well written document with an eample for your question.
They say,
Adding a watch in Android Studio on a RealmObject will display values of the fields. Unfortunately these values are wrong because the field values are not used. Realm creates a proxy object behind the scenes and overrides the getters and setters in order to access the persisted data in the Realm. Adding a watch for any of the accessors will yield correct values.
In the image above the debugger has stopped on line 113. There are three watch values, the person variable and the person.getName() and person.getAge() accessors. The code from lines 107 to 111 alters the person instance by changing the name and age. These values are then persisted in a transaction. On line 113, where the debugger is currently paused, the person watch instance is reporting on field values and they are incorrect. The watch values that use the accessor for person.getName() and person.getAge() report values that are correct.
Please note, the .toString() method will output the correct values but the watch panel will not (when watching a variable which is a RealmObject).
Read More Here
Hope it helps!

Realm - Skip writing nested objects programatically

I have seen the use of #Ignore for certain fields but I’m looking for something slightly different. https://realm.io/docs/java/latest/#models
Is it possible to specify skipping a nested object when writing a parent object to realm?
The reason for this:
I have a complex JSON object which I’m parsing and then saving to my Realm.
This object can get really large so there is some optimisation on my backend to return:
A complete object
A preview object
At some points I get a preview user object which returns only a subset of fields.
When saving to realm this overwrites the complete object (as expected) and wipes the fields not present.
The problem is that I still need those wiped fields later on.
You are not using the JSON support of Realm? If so you can use this, see last item (my emphasis):
Parsing JSON with Realm is subject to the following rules.
Creating object with JSON which has the field with a null value:
For a not-required field, set it to null which is the default value.
For a required field, throw an exception.
Updating object with JSON which has the field with a null value:
For a not-required field, set it to null.
For a required field, throw an exception.
JSON doesn’t have the field: Leave the value unchanged for both required and not-required fields.
Source:
https://realm.io/docs/java/latest/#json

What is mId in activeandroid and when can it be null?

I am creating and trying to save a table using active android but for some reason the object fails to save. The error that I get is
java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
Upon debugging the decompiled Model.class file I observed that an exception occurs while executing the following statement
(Please note that the below line is from the decompiled Model.class file of activeandroid)
long entityId1 = ((Model)e).getId().longValue();
It fails and the above said exception occurs. In the catch block I observe that for all non-primitive type fields the mId is non null, but for the field where the exception occurs the mId is null. I tried to search the web but could only find one line about mId.
ActiveAndroid automatically creates another auto-increment ID column. This is mId.
Then why does it fail to do so in this case. Does somebody have an idea? Thanks !!
OK I found the answer.
From codepath I found that
The problem is that This is because ActiveAndroid needs you to save
all objects separately. Before saving a tweet for example, be sure to
save the associated user object first. So when you have a tweet that
references a user be sure to user.save() before you call tweet.save()
since storing the user requires the local id to be set and assigned as
the foreign key for the tweet.
Thus I had to save my non primitive type object field first before saving the object.

Realm Find Queries Result in Empty Objects [duplicate]

This question already has answers here:
Cannot retrieve field values from realm object, values are null in debugger
(5 answers)
Closed 5 years ago.
When doing find queries for objects I'm getting "empty" objects (non-null, but not populated). However, in the debugger I can see the data for the object in the object description (see below). I've also verified the data is there using the Realm Browser. I've tried different find queries, querying with filter criteria, using the same Realm object for inserts/queries, using different Realm objects for inserts/queries, refreshing the Realm, etc.
If I Log fields in the RealmObject I see the proper data print out. However, I'm trying to convert these models into other models for use in RxJava per https://realm.io/news/using-realm-with-rxjava/.
Here's some sample code where reproduced the issue. Below that is a screenshot when breaking at verifyRealm.close().
RealmTester realmTester1 = new RealmTester();
realmTester1.setFirstName("Tester1");
realmTester1.setLastName("ABC");
RealmTester realmTester2 = new RealmTester();
realmTester2.setFirstName("Tester2");
realmTester2.setLastName("XYZ");
Realm insertRealm = Realm.getDefaultInstance();
insertRealm.refresh();
insertRealm.beginTransaction();
insertRealm.copyToRealm(realmTester1);
insertRealm.copyToRealm(realmTester2);
insertRealm.commitTransaction();
insertRealm.close();
Realm verifyRealm = Realm.getDefaultInstance();
RealmResults<RealmTester> verifyTesters = verifyRealm.where(RealmTester.class).findAll();
verifyRealm.close();
I have a screenshot of the debugger at: http://i.stack.imgur.com/1UdRr.png
I'm using v0.82.1. Any thoughts on why the models here aren't populating?
The idea behind realm-java is that we are generating Proxy class inherits from user's model class, and override the setters and getters there.
It is totally normal that you see null values for the model's field in the debugger, since the Realm are not setting them. (zero-copy, Realm is trying to reduce the memory usage by managing the data in the native code and sharing them whenever it is possible.)
Because of this, when you want to access a Realm model's field, please always use setters and getters. Checking the generated Proxy class will help you to understand this, it is quite simple actually. It is located in the build directory named like MyModelRealmProxy.java
And also check this section of the documents, it would give you some idea about the standalone object and how to write them to Realm.

How to make sure saving ParseObject and ParseRelation using saveEventually()

I have started using Parse library recently for Android app. I want to store user contacts using saveEventually and then use the ParseRelation to relate the same to user. As there are multiple contacts mapped to user, I am using below code to handle my save functionality.
ParseRelation relation = ParseUser.getCurrentUser().getRelation(relationshipName);
for(int entityIndex = 0; entityIndex < entities.length;entityIndex++) {
...
entity[entityIndex].saveEventually(); relation.add(entity[entityIndex]);
...
}
ParseUser.getCurrentUser().saveEventually();
Here I am using saveEventually() for each valid entity (ParseObject) and then adding the same to relation. Later once all the objects are added to ParseRelation, at the end I am calling saveEventually() for ParseUser to store all the relationship to Parse.
Is this approach right? I am getting below exception at relation.add(entity[entityIndex]);
All objects in a relation must have object ids.
It seems this suggest some network connectivity issue and ParseRelation is not getting unique objectId for each ParseObject, but I was assuming that this saveEventuall() will handle this scenario well with ParseRelation
Kindly suggest. I am using Parse library version 1.1.11
Thanks.
Any object that's added to a ParseRelation must be saved first. The saveEventually call is non-blocking, so it's unlikely that the object will already have been saved by the time execution reaches the very next line when it's added to a ParseRelation.
Since you need to make sure the object is saved first, you should use saveInBackground instead of saveEventually. Then make sure to add the saved object to the relation from inside saveInBackground's SaveCallback. This will ensure that the object has been saved before being added to the relation.

Categories

Resources