Home » Android » android – Primary key constraint broken. Value already exists: 0

android – Primary key constraint broken. Value already exists: 0

Posted by: admin June 15, 2020 Leave a comment

Questions:

Created organization:

    Organization organization = realm.createObject(Organization.class); // Create a new object
    OrganizationId organizationId = realm.createObject(OrganizationId.class);
    organizationId.setAggregateId("1");
    organization.setOrganizationId(organizationId);
    organization.setOrganizationName("1-я Клиника Ташкентской Медицинской Академии");
    organization.setAddress("Адрес: г. Ташкент, ул. Фароби, 2");
    organization.setPhoneNumber("Тел.: (+99871) 214-51-01, 214-50-86, 214-50-43");
    organization.setKey(organization.getOrganizationName().toLowerCase());

When I add new doctor with this organization everything is alright. App is working without any error:

    Doctor doctor = realm.createObject(Doctor.class);
    //FULL NAME
    FullName fullName = realm.createObject(FullName.class);
    fullName.setFirstName("Joe");
    fullName.setLastName("Richard");
    fullName.setMiddleName("Brown");
    doctor.setFullName(fullName);
    //CONTACTS
    Contacts contacts = realm.createObject(Contacts.class);
    RealmList<PhoneNumber> phoneNumberRealmList = new RealmList<>();
    PhoneNumber pn = realm.createObject(PhoneNumber.class);
    pn.setPhoneNumber("+998903735173");
    phoneNumberRealmList.add(0, pn);
    contacts.setPhoneNumbers(phoneNumberRealmList);
    doctor.setContacts(contacts);
    //ORGANIZATION
    doctor.setOrganization(organization);
    //SPECIALIZATION
    RealmList<Specialization> specializationRealmList = new RealmList<>();
    Specialization specialization = realm.createObject(Specialization.class);
    specialization.setSpecializationName("Ревматолог");
    specializationRealmList.add(0, specialization);
    doctor.setSpecializationList(specializationRealmList);

When I add second doctor I am getting error (error stack is down below):

Doctor doctor2 = realm.createObject(Doctor.class);//
//FULL NAME
FullName fullName2 = realm.createObject(FullName.class);
fullName2.setFirstName("Bob");
fullName2.setLastName("Richardson");
fullName2.setMiddleName("Brownowich");
doctor2.setFullName(fullName2);
//CONTACTS
Contacts contacts2 = realm.createObject(Contacts.class);
RealmList<PhoneNumber> phoneNumberRealmList2 = new RealmList<>();
PhoneNumber pn2 = realm.createObject(PhoneNumber.class);
pn2.setPhoneNumber("+998903720757");
phoneNumberRealmList2.add(1, pn2);
contacts2.setPhoneNumbers(phoneNumberRealmList2);
doctor2.setContacts(contacts2);
//ORGANIZATION
doctor2.setOrganization(organization);
//SPECIALIZATION
RealmList<Specialization> specializationRealmList2 = new RealmList<>();
Specialization specialization2 = realm.createObject(Specialization.class);
specialization2.setSpecializationName("Уролог");
specializationRealmList2.add(1, specialization2);
doctor2.setSpecializationList(specializationRealmList2);

Error is actually like this:

Process: uz.sunet.wm, PID: 5505
java.lang.RuntimeException: Unable to start activity ComponentInfo{uz.sunet.wm/uz.sunet.wm.activities.MainActivity}:
io.realm.exceptions.RealmException: Primary key constraint broken.
Value already exists: 0
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: io.realm.exceptions.RealmException: Primary key constraint broken. Value already exists: 0
at io.realm.internal.Table.throwDuplicatePrimaryKeyException(Table.java:731)
at io.realm.internal.Table.addEmptyRow(Table.java:380)
at io.realm.Realm.createObject(Realm.java:1037)
at uz.sunet.wm.data.MyRealm.initiateRealmData(MyRealm.java:88)
at uz.sunet.wm.activities.MainActivity.onCreate(MainActivity.java:60)
at android.app.Activity.performCreate(Activity.java:5264)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
            at android.os.Handler.dispatchMessage(Handler.java:110)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:5292)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
            at dalvik.system.NativeStart.main(Native Method)

I have no idea what is happening. For the first doctor I set id – 0. Second – 1. However I am getting this error. What I am doing wrong? How to solve this problem?

How to&Answers:

It is because you are using Realm.createObject() together with a model class that has a primary ID. When you use createObject() a new object is created with default values, incl. 0 for the primary key. If you already have an object with primary key 0, a primary key violation error will be thrown, just like in your case.

You have two options:

1) Never use 0 as a primary key value for your objects, as that will prevent further calls to Realm.createObject(). This also implies that you cannot call this method two times in a row.

2) Use standalone objects and then use Realm.copyToRealm() or Realm.copyToRealmOrUpdate(). This will enable Realm to check the primary value before creating any objects inside Realm.

I would recommend the later approach as it is less error prone.