ivava
ivava

Reputation: 23

prevent greenDAO inserting duplicate entry

I have an activity that will parse json data and update database using greenDAO once the activity start. It update code is like :

exampleDao.insertOrReplace(exampleObj);

but when the activity back and resume, it will keep on insert causing duplicate data entry with different primary key but same data, how to prevent duplicate data entry?

Thanks alot

Upvotes: 2

Views: 6769

Answers (4)

Vasiliy
Vasiliy

Reputation: 16238

The solution by @Hiep is in right direction, but is not completely correct: there is no need to change table's primary key.

In fact, it is enough to add @Unique annotations on all entity's fields which should be compared for equation, and GreenDao will handle the rest: if the entity you are inserting using insertOrReplace is equal on ALL unique fields to some already stored entity, then the old entity will be removed and the new one added.

Please note that this "swap" is effectively an update, but the row ID (primary key) of the "updated" entity will be different (therefore the method is called insertOrReplace).

So, given the following entity:

@Entity
public static class TestEntity {

    @Id(autoincrement = true)
    private Long id;

    @Unique @NotNull private String code;

    @NotNull private String description;

    // constructor and getters/setters here
}

The following test passes (you can run it with Robolectric):

@Test
public void insertOrReplace_nullRowIdSameUniqueField_existingEntryReplaced() {
    // Arrange
    TestEntity testEntity = new TestEntity(null, "code", "old description");
    mDaoSession.getTestEntityDao().insert(testEntity);

    assertThat(mDaoSession.getTestEntityDao().loadAll().size(), is(1)); // assert insertion succeeded

    // Act
    TestEntity testEntityOther = new TestEntity(null, "code", "new description");
    mDaoSession.getTestEntityDao().insertOrReplace(testEntityOther);

    // Assert
    List<TestEntity> testEntityList = mDaoSession.getTestEntityDao().loadAll();

    assertThat(testEntityList.size(), is(1)); // number of entities did not change
    assertEquals(testEntityList.get(0).getCode(), "code"); // same code
    assertEquals(testEntityList.get(0).getDescription(), "new description"); // updated description
}

Upvotes: 1

Hiep
Hiep

Reputation: 2612

Make a column (other from your_Id) unique, and use it as real primary key.

Upvotes: 2

Markus Junginger
Markus Junginger

Reputation: 7075

Make sure your entity has it's primary key property set (!= null).

Upvotes: 0

AlexS
AlexS

Reputation: 5345

As you didn't provide a schema or similar information about your data model, this answer is only a guess!

Probably you are using autoincremented primary key.

This means your primary key is probably not included in your JSON data causing the primary key property to be null.

This tells greendao that this is a new entry and greendao will insert a new entry with a new primary key.

Try to read the object first and call then insertOrReplace:

Example oldObj;
try {
    // Try to find the Example-Object if it is already existing.
    oldObj = exampleDao.queryBuilder().where(someCondition).unique();
} catch (Exception ex) {
    oldObj = null;
}
if (oldObj == null) {
    oldObj = new Example();
}
// update oldObj with the data from JSON
exampleDao.insertOrReplace(oldObj);

Upvotes: 5

Related Questions