I have following class
public class Student extends RealmObject{
private int studentID;
private String studentName;
// getters and setters here
}
Then I try to set a value to a already created student object
student.setStudentName("Peter");
Then I get following error
java.lang.IllegalStateException: Mutable method call during read
transaction.
In order to overcome this I have to do it as follows
Realm realm = Realm.getInstance(this);
realm.beginTransaction();
student.setStudentName("Peter");
realm.commitTransaction();
I don't want to persist this change in the database. How can I just set/change a value to an realm object variable without always persisting it to the database?
If you want to modify the object in a non-persisted manner, you need an unmanaged copy of it.
You can create a copy using realm.copyFromRealm(RealmObject realmObject); method.
When you are using Realm.createObject(), the object is added to the Realm and it only works within a write transaction. You can cancel a transaction and thereby discard the object.
Moreover, you can use your model class as a standalone class and create objects in memory (see http://realm.io/docs/java/0.80.0/#creating-objects for details). If you need to persist the objects, you can use the Realm.copyToRealm() method.
You might want to create a new Model. And your new model should implement RealmModel.
public class StudentRM extends RealmModel{
private int studentID;
private String studentName;
// Constructors here
// getters and setters here
}
Now you can do this.
studentRm.setStudentName("Peter"); //Setting Vale Or
studentRm.addAll(student); //Add all value from DB
studentRm.setStudentName("Jhon"); //It won't change DB anymore
studentRm.getStudentName(); // "Jhon"
You can use realm.cancelTransaction();, instead of realm.commitTransaction();
Related
I need to delete elements from the database.
That's my code and I don't know if I am right
realm.executeTransaction(
realm1 -> {
RealmResults<UserWordRealm> result = realm1.where(UserWordRealm.class).equalTo("id",id).findAll();
result.deleteAllFromRealm();
}
);
}
In the RealmObject class, the id(PrimaryKey) field must uniquely identify the object. Therefore, there cannot be more than one element with the same id. Using findFirst() instead of findAll() may solve your problem.
To delete an object from a realm, use either the dynamic or static versions of the deleteFromRealm() method of a RealmObject subclass.
realm.executeTransaction(r -> {
UserWordRealm userWordObject = r.where(UserWordRealm.class).equalTo("id", id).findFirst();
userWordObject.deleteFromRealm();
// discard the reference
userWordObject = null;
});
I have an object like below,
class LocationData{
String time;
String name;
String address;
}
for this object i have created getter setter.
By using service i fill this above model and save into room database.
whenever user open my app i just update the room database data to server using API.
Now sometimes the time duplication occurred. How to remove the object from array based on time. time should be unique.
You can use the extension function distinctBy. If you have an array of LocationData objects called allLocations it would be
val distinctLocations = allLocations.distinctBy { it.time }
Note distinctLocations will be a List; if you want it to be an array, use toTypedArray()
Thanks in advance.
I have scenario where i wanted to check the data difference between existing and new realm model object.
Example
public class PostModel extends RealmObject {
#Required
#PrimaryKey
#Index
private String postId;
private String message;
}
Let say we have two objects
Old
PostModel old = new PostModel("one", "Welcome");
realm.copyToRealm(old);
New Object
PostModel newOne = new PostModel("one", "Welcome to World");
before updating the old object with newOne should check data change, if change is there then should insert in the realm, like below
realm.dirtyCheckAndUpdate(old, newOne);
//underlying it should do below
Getting the record with id "one"
Check the difference between db record and new record (!old.message.equalsIgnore(newOne.message)).
if change is there then copyToRealmOrUpdate() should happen.
I just gave an example, i need to to this for complex RealmModel with relationship.
Why do you need to check? You can just call copyToRealmOrUpdate()? It will update data regardless, but if it overrides the data with the same data the end result is the same.
Otherwise, you will be forced to implement all the checking yourself, which is time-consuming and error-prone. You could also make your own annotation processor that generated the logic for you. It would look something like:
public boolean compare(PostModel m1, PostModel m2) {
if (!m1.getId().equals(m2.getId()) return false;
if (!m1.getMessage().equals(m2.getMessage()) return false;
if (!PostModelReference.compare(m1.getRef(), m2.getRef()) return false; // Recursive checks
}
How do I create OR update a ForeignCollection in OrmLite?
If I try to simply add an object to a ForeignCollection, the add method acts as a create (insert into) method, but if the object already exists I will get an error about not having a unique primary key. I don't want duplicates to appear with autoincrementing primary keys, so this is fine to get this notice.
If I use the update method, then it will error if there is nothing to update.
It seems that the foreigncollection object doesn't have a way to tell me if an object is already existing in the database.
So is the only way to write a separate query myself, see if each object exists and drop the ones that have changed?
If you are using for example :
#DatabaseTable(tableName = "question")
public class QuestionDb implements Serializable {
#ForeignCollectionField(foreignFieldName = "question", eager = true)
private ForeignCollection<AnswerDb> answers;
}
#DatabaseTable(tableName="answers")
public class AnswerDb implements Serializable{
#DatabaseField (foreign=true,canBeNull=true,columnName=FIELD_QUESTIONID)
private QuestionDb question;
}
You will have to use the function createOrUpdate of the AnswersDB.
answerYouWantToAdd.setQuestion(yourQuestion);
answerDao.createOrUpdate(answerYouWantToAdd);
I want to persist an object with two foreignCollections.
But when I try to query the object, my foreignId is always null.
I already read this answers but it doesn't really help me: Collections in ORMLite
VOPerception perception = new VOPerception();
perception.setOrientation(daoOrientation.createIfNotExists(
orientationLocalizer.getCurrentOrientation()));
ForeignCollection<VOAccessPoint> fAp =
daoPerception.getEmptyForeignCollection("accessPoints");
fAp.addAll(wifiLocalizer.getCurrentScanResultMap());
perception.setAccessPoints(fAp);
daoPerception.create(perception);
List<VOPerception> list = daoPerception.queryForAll();
here data are correctly stored but VOAccessPoint objects have no link with the parent VOPerception object.
Here are my two classes:
public class VOPerception {
#DatabaseField(generatedId=true)
private int per_id;
#ForeignCollectionField(eager=true)
ForeignCollection<VOAccessPoint> accessPoints;
...
}
public class VOAccessPoint{
#DatabaseField(generatedId=true)
private int ap_id;
#DatabaseField(foreign=true,columnName="apForeignPerception_id")
private VOPerception apForeignPerception;
...
}
Your queryForAll() is returning no objects because none of your VOAccessPoint instances ever set their apForeignPerception field to be perception. Adding the VOAccessPoint objects using the ForeignCollection added them to the DAO but did not automagically assign their apForeignPerception field.
You should do something like:
...
Collection<VOAccessPoint> points = wifiLocalizer.getCurrentScanResultMap();
for (VOAccessPoint point : points) {
point.setApForeignPerception(perception);
}
fAp.addAll(points);
...
I can see how you might think that this would be handled automagically but at the time they are added to the ForeignCollection, the perception is not even assigned. I suspect that there is a missing feature for ORMLite here or at least a better exception.
I would recommend to use assignEmptyForeignCollection(Obj parent, fieldName). This will create a new foreign collection and all objects you will add via add(Obj element) will have the parent value set automatically.