Android Realm - RealmObject returning after deletion - android

I'm running in to an issue where I delete a RealmObject (and confirm its gone using StethoRealm), but when I create and save a new RealmObject with the same variable value, the deleted RealmObject reappears along with my new RealmObject.
With the below object - I delete the myObject1 by matching the 'id', but when I create a new MyObject myObject2 with the same 'name' both objects appear in my realm
Any tips on why this might be happening?
Example:
public class MyObject extends RealmObject {
#PrimaryKey
private String id;
private String name;
// getters and setters
}
Edit
Delete call
#Override
public void deleteMyObjectById(final String id, final OnDeleteMyObjectById callback) {
Realm realm = new MyRealmConfiguration().getDefaultRealm();
final RealmResults<MyObject> myObjects = realm.where(MyObject.class).equalTo(RealmTable.MyObject.ID, id).findAll();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
myObjects.deleteAllFromRealm();
if (callback != null) {
callback.onSuccess();
}
}
});
realm.close();
}
Add call
#Override
public void addMyObject(MyObject myObject, OnSaveMyObjectCallback callback) {
Realm realm = new MyRealmConfiguration().getDefaultRealm();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(myObject);
if (callback != null) {
callback.onSuccess();
}
}
});
realm.close();
}

I'm not sure as to how you are deleting your objects. The way I'm deleting them (and it works) is...
final RealmResults<UserCredentials> credentialResults = realm.where(UserCredentials.class).findAll();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
credentialResults.deleteAllFromRealm();
}
});
realm.close();
Of course, you are using MyObject instead of UserCredentials, and you aren't deleting everything of that type, but it should be similar enough. Try using executeTransaction and realm.close() if you aren't already.

Try something like this. get the instance inside transcation method and delete. i have been using this for one of my app. and it works fine with deletion process
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
RealmResults<MyObject> myObjects = realm.where(MyObject.class).equalTo(RealmTable.MyObject.ID, id).findAll();
myObjects.deleteAllFromRealm();
}
});

Related

How to return value when Realm transaction success?

I have this method, i want return value when the transaction complete, but i cant. This's my code
public List<Group> getConversations() {
final RealmResults<Group> conversations;
try {
mRealm = Realm.getDefaultInstance();
mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
RealmResults<Group> conversations = realm.where(Group.class).findAllSorted("time", Sort.DESCENDING);
cursorConversation(conversations);
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
//return conversation
}
});
}
return null;
}
What should i do ?
I am not sure what are you doing in cursorConversation(..) but you can use the same method on returned values from Realm.
give a try
public List<Group> getConversations() {
try (Realm realm = Realm.getDefaultInstance()) {
return realm.copyFromRealm(realm.where(Group.class).findAllSorted("time", Sort.DESCENDING));
}
}
You don't need to run a transaction for getting the conversations. You can run your query on the realm db and add a change listener to the result. When the query completes, it'll call that change listener with the RealmResults<Converstaion>, Check this link for more.
Something like
public void listenToConversations(RealmChangeListener<RealmResults<Conversation>> listener) {
RealmResults<Conversations> conversations = realm.where(Group.class).sort("time", Sort.DESCENDING).findAllAsync();
conversations.addChangeListener(listener);
}
where listener is something like
listener = new RealmChangeListener<RealmResults<Conversations>>() {
\#Override
public void onChange(RealmResults<Conversations> conversations) {
// React to change
}
}
You'll also need to remove listener to avoid any memory leaks.

How to insert into realm database with specific position and how to retrieve the data with that position in android?

I am using retrofit to parse youtube api json data and used tablayout and viewpager.titles are coming correctly and the data is only coming for the first youtube playlist and the same repeating for the other fragments.saved data to realm like this
private void setAdapterVideos(final List<YoutubeVideoDetails> items, final List<YoutubePlayListVideos> videosList) {
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(items);
realm.copyToRealmOrUpdate(videosList);
}
});
}`
and retrieved the data like this
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
videosList = realm.where(YoutubePlayListVideos.class).findAll();
videoDetails = realm.where(YoutubeVideoDetails.class).findAll();
}
});
if (videosList.size() > 0) {
new LogUtil("aaaaaaaaaaa",posi+": "+videosList.get(0).getSnippet().getTitle());
VideoAdapter vAdapter = new VideoAdapter(getActivity(), videosList, videoDetails);
recyclerView.setAdapter(vAdapter);
progressBar.setVisibility(View.GONE);
}
I am new to realm database used only SQ Lite and any help would be appreciated...!

How works delete in realm with relationship?

I have this classes
class Student extends RealmObject {
public String code;
public String name;
public String email;
public Course course;
}
class Course extends RealmObject {
public String code;
public String name;
}
class Sync {
// ...
// To sync data I am using retrofit, look the method to update course
public void onResponse(Call<...> call, Response<...> response) {
if (response.isSuccessful()) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.delete(Course.class);
realm.copyToRealm(response.body());
}
});
}
}
}
After call Sync to update Courses, all Student object has its course setting to null, this is expected behavior after called realm delete?
Even after table is populated again, the course on Student is still null.
Today I made this change on the code:
class Course extends RealmObject {
#PrimaryKey
public String code;
public String name;
}
class Sync {
// ...
// To sync data I am using retrofit, look the method to update course
public void onResponse(Call<...> call, Response<...> response) {
if (response.isSuccessful()) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response.body());
}
});
}
}
}
I made this too late to avoid delete the courses.
There is something that can I do to recovery the references courses and set it again to student?
Thank you.
This is expected behavior, because you invalidate the object links by deleting the objects you are pointing to.
To restore them, you would have to set the links again.
Another solution would be to not delete courses that you still need. This would be done if you annotate code with #PrimaryKey, that way you would "update" courses that are already in. Then the problem would be removing courses/students no longer in the response, but there are solutions ready-made for that.
public class Robject extends RealmObject {
#PrimaryKey
private String code;
#Index
private String name;
//...
#Index
private boolean isBeingSaved;
//getters, setters
}
And
// background thread
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Robject robject = new Robject();
for(Some some : somethings) {
robject.set(some....);
realm.insertOrUpdate(robject);
}
realm.where(Robject.class)
.equalTo(Robject.IS_BEING_SAVED, false) // compile 'dk.ilios:realmfieldnameshelper:1.1.0'
.findAll()
.deleteAllFromRealm(); // delete all non-saved data
for(Robject robject : realm.where(Robject.class).findAll()) { // realm 0.89.0+
robject.setIsBeingSaved(false); // reset all save state
}
}
});
} finally {
if(realm != null) {
realm.close();
}
}

Items not getting deleted from realm

io.realm:realm-gradle-plugin:2.0.0'
Android Studio 2.2.2
I am trying to delete objects from the realm database. The items seems to get deleted. But when I close the app and load items from the database the deleted ones still seem to have a reference to them. This is my code below for deleting.
If the delete onSuccess is called I send back the item to be removed from the recyclerview's adapter. Is this the correct way to do this?
#Override
public void deletePerson(final Person person, final DeleteListener deleteListener) {
mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
RealmResults<Person> results = realm.where(Person.class).equalTo("mId", person.getId()).findAll();
results.deleteAllFromRealm();
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
/* send the person object back to be removed from the recyclerview after success*/
deleteListener.onDeleteSuccess(person);
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
deleteListener.onDeleteFailure(error.getMessage());
}
});
}
And when I load the persons the ones that are deleted seem to have a reference in realm and doesn't seem to be completely removed.
#Override
public void loadPersons(final LoadPersonListener loadPersonListener) {
if(mRealm.isClosed()) {
mRealm = Realm.getDefaultInstance();
}
RealmResults<Person> personsList = mRealm.where(Person.class).findAll();
if(personsList.size() > 0) {
loadPersonListener.onLoadPersonSuccess(personsList);
}
else {
loadPersonListener.onLoadPersonFailure("No items in the database");
}
}
You aren't removing anything from the Realm at the moment, you're just querying. Also, you're accessing the Person you sent in on a background thread, which ought to throw IllegalStateException.
So instead of
#Override
public void deletePerson(final Person person, final DeleteListener deleteListener) {
mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
RealmResults<Person> results = realm.where(Person.class).equalTo("mId", person.getId()).findAll();
}
You should have
#Override
public void deletePerson(final Person person, final DeleteListener deleteListener) {
final String id = person.getId();
mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.where(Person.class).equalTo("mId", id).findAll().deleteAllFromRealm();
}
Here in you code you only query data asynchronously. For deletion use .remove() method while looping on result of query.
Suppose, that mId is #Primary key, removal will look like:
RealmResults<Person> results = realm.where(Person.class).equalTo("mId", person.getId()).findFirst().removeFromRealm();

Android Realm - copyToRealmOrUpdate clears RealmList

I have a Realm object "TaskEntity" which has RealmList field.
public class TaskEntity extends RealmObject {
...
private RealmList<ContextEntity> contexts;
}
I make new instance of this entity through constructor and copy values of fields from Realm object.
TaskEntity task = mRealm.where(TaskEntity.class).findFirst();
TaskEntity newTask = new TaskEntity();
newTask.setId(task.getId());
newTask.setName(task.getName());
newTask.setContexts(task.getContexts()); //copying of RealmList
When user makes some changes and wants to save it I call copyToRealmOrUpdate.
mRealm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
mRealm.copyToRealmOrUpdate(newTask);
}
});
Sometimes old state has several items in RealmList and user doesn't make changes in that field. So when I call copyToRealmOrUpdate, RealmList becomes empty.
newTask.getContexts().size(); // 2 items
mRealm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
mRealm.copyToRealmOrUpdate(newTask);
}
});
newTask.getContexts().size(); // 0 items
How can I fix it?

Categories

Resources