Realm-java: Issue in realm relationships: Many-to-One, it creates duplicate objects

Created on 4 May 2016  Â·  2Comments  Â·  Source: realm/realm-java

Goal

2 Contact and 1 Email object in realm database.

Actual Results

Different way create different results.

Steps & Code to Reproduce

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.
enter image description here

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();

enter image description here
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?

Version of Realm and tooling

Realm version(s): ?
0.88.3
Android Studio version: ?
2.0
Which Android version and device: ?
Android 4.4

I already asked a question on stackoverflow: here, but there is no satisfactory answer. Looking forward to your reply! Thanks!

T-Help

Most helpful comment

After set a @PrimaryKey both in Contactand Email, and call copyToRealmOrUpdate(contactA)andcopyToRealmOrUpdate(contactB). The relationships betweens Contactand Email was correctly in situation 1.

Thanks a lot! And you can close this issue now.

All 2 comments

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.

After set a @PrimaryKey both in Contactand Email, and call copyToRealmOrUpdate(contactA)andcopyToRealmOrUpdate(contactB). The relationships betweens Contactand Email was correctly in situation 1.

Thanks a lot! And you can close this issue now.

Was this page helpful?
0 / 5 - 0 ratings