CreateOrUpdate() всегда создает новую запись в базе данных с ORMLite

В моем Android-проекте ORMLite работает как кеш. Я загружаю данные с веб-сервера и помещаю его в базу данных. Я вызываю createOrUpdate для своих объектов, но дубликаты появляются в базе данных. Записи базы данных идентичны, за исключением первичного ключа (который является просто автоматически увеличивающимся целым числом). Я думаю, что, поскольку у моего второго объекта еще нет первичного ключа, ORMLite считает, что эти два являются разными, хотя каждое другое поле идентично.

Кто-нибудь знает, верно ли это?

Ответ 1

Вы не должны вызывать createOrUpdate, если у вашего объекта уже нет поля идентификатора. Способ ORMLite определяет, существует ли он в базе данных, чтобы он выполнял запрос по идентификатору. В коде есть:

ID id = extractId(data);
// assume we need to create it if there is no id  <<<<<<<<<<<<<<<<<<<<<<<
if (id == null || !idExists(id)) {
    int numRows = create(data);
    return new CreateOrUpdateStatus(true, false, numRows);
} else {
    int numRows = update(data);
    return new CreateOrUpdateStatus(false, true, numRows);
}

Я расширю javadocs, чтобы объяснить это лучше. Они там очень слабые. Сожалею. Я обновил их:

Это удобный метод для создания элемента в базе данных, если он не существует. Идентификатор извлекается из аргумента данных, и запрос-по-идентификатору делается в базе данных. Если строка в базе данных с тем же идентификатором существует, то все столбцы в базе данных будут обновляться из полей в параметре данных. Если id имеет значение null (или 0 или какое-либо другое значение по умолчанию) или не существует в базе данных, тогда объект будет создан в базе данных. Это также означает, что ваш элемент данных должен иметь определенное поле идентификатора.

Ответ 2

Кажется, вам нужно вручную извлечь идентификатор уже существующей записи, а затем update базу данных на основе вашего фактического уникального идентификатора. Пример с уникальными URL-адресами:

CacheItem newEntry = fetchEntry("..."); // fetch it here
List<CacheItem> existing = mDao.queryForEq("url", newEntry.getUrl());
if (existing.size() > 0) {
    int id = existing.get(0).getId();
    newEntry.setId(id);
    mDao.update(newEntry);
} else mDao.create(newEntry);

Ответ 3

установите свой первичный ключ для нормальной работы.

@DatabaseField (columnName = "id", uniqueIndex = true) private int id;

Работал для меня. Исключения выбрасываются на фоне, но он работает: D