Skip to content Skip to sidebar Skip to footer

Execute Transaction Method Using Realm Continues To Loop On Each Run Android

In my app I am using Realm DB to store all the data in local database. I have some initial mock data which I want to show at the starting of the app. Previously I implemented begin

Solution 1:

That's because in onCreate(), you run basicCRUD(personRealm); which adds new person models

            PersonModel model = new PersonModel();
            model.setId(1 + System.currentTimeMillis());
            model.setName("Name1");
            model.setCompany("Comapny1");
            model.setTitle("Title1");
            person.add(model);

As you set id as 1 + System.currentTimeMillis(), it will be a new object with a different primary key, and it gets inserted. If it were just 1, 2 and so on then it'd update them as the same object.

Thankfully, Realm provides the initialData(Realm.Transaction) method on the RealmConfiguration.Builder() which allows you to create the initial data for the database only when the database is first created, or if the data is deleted after deleteRealmIfMigrationNeeded().

publicclassInitialDataimplementsRealm.Transaction {
    @Overridepublicvoidexecute(Realm realm) {
        List<PersonModel> person = newArrayList<>();
        PersonModel model = newPersonModel();
        model.setId(1 + System.currentTimeMillis());
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        person.add(model);

        model = newPersonModel();
        model.setId(2 + System.currentTimeMillis());
        model.setName("Name2");
        model.setCompany("Company2");
        model.setTitle("Title2");
        person.add(model);

        model = newPersonModel();
        model.setId(3 + System.currentTimeMillis());
        model.setName("Name3");
        model.setCompany("Company23");
        model.setTitle("Title3");
        person.add(model);

        model = newPersonModel();
        model.setId(4 + System.currentTimeMillis());
        model.setName("Name4");
        model.setCompany("Comapny4");
        model.setTitle("Title4");
        person.add(model);

        for (PersonModel realmModel : person) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Overridepublicbooleanequals(Objectobject) {
        returnobject != null && objectinstanceofInitialData;
    }

    @Overridepublic int hashCode() {
        returnInitialData.class.hashCode();
    }
}

And

Realm.init(this);
Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
                                    .deleteRealmIfMigrationNeeded()
                                    .initialData(new InitialData())
                                    .build());

EDIT:

To provide multiple "initial datas" in only one "initial data" (as you provide 1 transaction), you can rely on the composite design pattern to provide multiple initial datas in just one initial data, like so

public final classInitialDataPersonsimplementsRealm.Transaction {
    @Overridepublicvoidexecute(Realm realm) {
        List<PersonModel> person = newArrayList<>();
        PersonModel model = newPersonModel();
        model.setId(1 + System.currentTimeMillis());
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        person.add(model);

        model = newPersonModel();
        model.setId(2 + System.currentTimeMillis());
        model.setName("Name2");
        model.setCompany("Company2");
        model.setTitle("Title2");
        person.add(model);

        model = newPersonModel();
        model.setId(3 + System.currentTimeMillis());
        model.setName("Name3");
        model.setCompany("Company23");
        model.setTitle("Title3");
        person.add(model);

        model = newPersonModel();
        model.setId(4 + System.currentTimeMillis());
        model.setName("Name4");
        model.setCompany("Comapny4");
        model.setTitle("Title4");
        person.add(model);

        for (PersonModel realmModel : person) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Overridepublicbooleanequals(Objectobject) {
        returnobject != null && objectinstanceofInitialDataPersons;
    }

    @Overridepublic int hashCode() {
        returnInitialDataPersons.class.hashCode();
    }
}

and

public final classInitialDataNewsimplementsRealm.Transaction {
    @Overridepublicvoidexecute(Realm realm) {
        List<NewsModel> newsItem = newArrayList<>();
        NewsModel model = newNewsModel();

        model.setId(1+System.currentTimeMillis());
        model.setImage(R.drawable.image1);
        model.setTitle("title1");
        model.setDate("12.07.2017");
        model.setDetail("deascription");
        newsItem.add(model);

        model = newNewsModel();
        model.setId(3+System.currentTimeMillis());
        model.setImage(R.drawable.image3);
        model.setTitle("title2");
        model.setDate("05.05.2017");
        model.setDetail("description");
        newsItem.add(model);

        model = newNewsModel();
        model.setId(4+System.currentTimeMillis());
        model.setImage(R.drawable.image4);
        model.setTitle("title3");
        model.setDate("13.04.2017");
        model.setDetail("description3");
        newsItem.add(model);

        .....

        for (NewsModel realmModel : newsItem) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Overridepublicbooleanequals(Object obj) {
        return obj != null && obj instanceofInitialDataNews;
    }

    @Overridepublic int hashCode() {
        returnInitialDataNews.class.hashCode();
    }
}

and

public final classCompositeInitialDataimplementsRealm.Transaction {
    private final Realm.Transaction[] transactions;

    privateCompositeInitialData(Realm.Transaction... transactions) { // `of` is prettierthis.transactions = transactions;
    }

    publicstaticCompositeInitialDataof(Realm.Transaction... transactions) {
        returnnewCompositeInitialData(transactions);
    }

    @Overridepublicvoidexecute(Realm realm) {
        for(Realm.Transaction transaction : transactions) {
            transaction.execute(realm);
        }
    }

    @Overridepublicbooleanequals(Object obj) {
        return obj != null && obj instanceofCompositeInitialData; // you might want autogenerated equals instead
    }

    @Overridepublic int hashCode() {
        returnCompositeInitialData.class.hashCode(); // you might want autogenerated hashCode instead
    }
}

This way you can provide

Realm.init(this);
Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
             .deleteIfMigrationNeeded()
             .initialData(CompositeInitialData.of(new InitialDataNews(), new InitialDataPersons()))
             .build());

Post a Comment for "Execute Transaction Method Using Realm Continues To Loop On Each Run Android"