Reputation: 9142
Following the official documents guide: Realm Relationships
I tried to write some code of Many-to-One relationship, and I found some things that are not consistent.
Two POJO Contace.java
and Email.java
are defined as follows:
public class Email extends RealmObject {
private String address;
private boolean active;
// ... setters and getters left out
}
public class Contact extends RealmObject {
private String name;
private Email email;
// ... setters and getters left out
}
Situation 1: Create a normal Email
object and assign to different Contact
contactA and contactB.
Email email = new Email();
email.setAddress("[email protected]");
email.setActive(true);
Contact contactA = new Contact();
contactA.setName("Bear");
contactA.setEmail(email);
Contact contactB = new Contact();
contactB.setName("Monkey");
contactB.setEmail(email);
realm.beginTransaction();
realm.copyToRealm(contactA);
realm.copyToRealm(contactB);
realm.commitTransaction();
After I call realm.copyToRealm()
, two Email
objects will be created here. So, when I query Contact
from Realm, one Email
object will become two different object? I think this is not a Many-to-One relationship anymore, it just become One-to-One relationship.
Situation 2: Call realm.createObject()
to create a proxy Email
object and two proxy Contact
object, and assign email to contactA and contactB.
realm.beginTransaction();
Email email = realm.createObject(Email.class);
email.setAddress("[email protected]");
email.setActive(true);
Contact contactA = realm.createObject(Contact.class);
contactA.setName("Bear");
contactA.setEmail(email);
Contact contactB = realm.createObject(Contact.class);
contactB.setName("Monkey");
contactB.setEmail(email);
realm.commitTransaction();
Here we can see just one Email object in the table, and that's what I expected, just as described in the document above.
So, why is there no consistency in situation1 and situation2? Is it a bug in situation1? Or am I missing something?
Realm version(s):0.88.3
Android Studio version:2.0
Looking forward to your reply! Thanks!
Upvotes: 2
Views: 937
Reputation: 9142
Thanks for beeender's answer here: [issue-2730]
This is the expected behaviour.
In the situation1, the email you set to contactA and contactB is a standalone object which is not managed by Realm. So when you copy it to Realm, Realm has no way to know you mean they are the same object. To solve this, you can add a @PrimaryKey to Email and then use copyToRealmOrUpdate. Realm will try to detect if you mean the same email object for both contactA and contactB based on the primary key.
In the situation2, since the email object is managed by Realm, when you call setters, Realm knows that email is actually the same one.
Finally I set a @PrimaryKey
both in Contact
and Email
, as following:
public class Email extends RealmObject {
@PrimaryKey
private String address;
private boolean active;
// ... setters and getters left out
}
public class Contact extends RealmObject {
@PrimaryKey
private String name;
private Email email;
// ... setters and getters left out
}
Then change copyToRealm()
to copyToRealmOrUpdate()
on contactA and contactB.
realm.beginTransaction();
realm.copyToRealmOrUpdate(contactA);
realm.copyToRealmOrUpdate(contactB);
realm.commitTransaction();
And the relationships betweens Contact
and Email
was correctly in situation 1.
Upvotes: 1
Reputation: 12953
In the first case two email is created because you are doing copyToRealm
two times on different instance.
From the docs Each contact (instance of Contact) have either 0 or 1 email (instance of Email)
Upvotes: 0