GreenDao IndsertOrReplaceInTx вставить только последний элемент списка

У меня есть несколько POJOS и создать несколько таблиц для них. Все они работают хорошо, что означает, что я могу вставить их и загрузить их... кроме этого:

Мой список брендов содержит 6 элементов, и я действительно уверен, что они разные (поставьте точку останова и увидели их), но когда я собираюсь вставить их в БД, greenDao вставлен только последний элемент. Моя таблица пуста, и это утверждение предполагает ее заполнение.

коды:

public class SingletonDatabase {

    private static SingletonDatabase mInstance;
    private DaoMaster.OpenHelper mHelper;
    private DaoSession mDaoSessionForUI;
    private DaoMaster mDaoMaster;
    private static Context mCtx;

    private SingletonDatabase(Context context) {
        mCtx = context;
        setupDb();
    }

    public static synchronized SingletonDatabase getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new SingletonDatabase(context);
        }
        return mInstance;
    }

    private void setupDb() {
        mHelper = new DaoMaster.OpenHelper(
                mCtx.getApplicationContext(), "mydb", null) {

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion,
                    int newVersion) {
                // Handle upgrade
            }
        };

        SQLiteDatabase db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSessionForUI = mDaoMaster.newSession();


    }

    public DaoSession getDaoSessionForUI() {
        return mDaoSessionForUI;

    }

    public DaoSession getDaoSeesion(){

        return mDaoMaster.newSession();
    }

}

Сгенерированный код бренда:

 * Entity mapped to table BRAND.
 */
public class Brand {

    private long tableId;
    private String id;
    private String name;
    private String publicImage;
    private String description;
    private String lastDownloadedTime;

    public Brand() {
    }

    public Brand(long tableId) {
        this.tableId = tableId;
    }

    public Brand(long tableId, String id, String name, String publicImage, String description, String lastDownloadedTime) {
        this.tableId = tableId;
        this.id = id;
        this.name = name;
        this.publicImage = publicImage;
        this.description = description;
        this.lastDownloadedTime = lastDownloadedTime;
    }

    public long getTableId() {
        return tableId;
    }

    public void setTableId(long tableId) {
        this.tableId = tableId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPublicImage() {
        return publicImage;
    }

    public void setPublicImage(String publicImage) {
        this.publicImage = publicImage;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getLastDownloadedTime() {
        return lastDownloadedTime;
    }

    public void setLastDownloadedTime(String lastDownloadedTime) {
        this.lastDownloadedTime = lastDownloadedTime;
    }

}

Код для создания схемы:

public class DaoGen {

    public static void main(String[] args) throws Exception {

        Schema schema = new Schema(1, "com.mmlooloo");

        Entity brandList = addBrand(schema);



        File f = new File("src-gen");
        f.mkdir();

        new DaoGenerator().generateAll(schema,f.getAbsolutePath());
    }

    private static Entity addBrand(Schema schema) {

        Entity brand = schema.addEntity("Brand");
        brand.addLongProperty("tableId").notNull().primaryKey().autoincrement();
        brand.addStringProperty("id");
        brand.addStringProperty("name");
        brand.addStringProperty("publicImage");
        brand.addStringProperty("description");
        brand.addStringProperty("lastDownloadedTime");
        return brand; 

    }

}

и наконец как я их вставляю:

public class BrandDownloadService extends IntentService {
public BrandDownloadService() {
    super("BrandDownloadService");

}
@Override
protected void onHandleIntent(Intent intent) {
    ....
    BrandDao brandDao = SingletonDatabase.getInstance(this).getDaoSeesion().getBrandDao();
    brandDao.insertOrReplaceInTx(brandList,true);

}

Я устанавливаю точку останова и проверяю brandlist и имеет 6 элементов.

Любая помощь, обойти, отладить советы... Я действительно не знаю, в чем проблема.

Большое спасибо!!

РЕДАКТИРОВАТЬ:

Я создал очень очень простой (очень простой, поверьте мне:-)) тестовый проект, который читает json из файла, анализирует его в списке и вставляет его в db, и проблема существует. Может кто-нибудь сказать мне, в чем моя ошибка? большое большое спасибо:-).

1 ответ

Решение

Вероятно, ваши 6 элементов бренда находятся в одной таблице. Таким образом, greendao считает, что это один элемент (идентифицируемый первичным ключом) и заменяет первый на второй, второй на третий и так далее...

Если вы использовалиnotNull().primaryKey().autoincrement()

Однажды у меня возникла та же проблема, и я "исправил" ее, изменив dao-шаблон, который используется для генерации кода в проекте dao-generator.

Возможно, это также будет работать, если вы не используете notNull() на свойство первичного ключа.

ОБНОВИТЬ

Я снова посмотрел на greendao:

В greendao-генератор, файл src-template/dao.ftl Вы можете найти следующие строки:

protected void bindValues(SQLiteStatement stmt, ${entity.className} entity) {
    stmt.clearBindings();
<#list entity.properties as property>
<#if property.notNull || entity.protobuf>
<#if entity.protobuf>
    if(entity.has${property.propertyName?cap_first}()) {
</#if>        stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, entity.get${property.propertyName?cap_first}()<#if
 property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()</#if>);

Это означает, что если вы используете notNull() на ваше autoincrement-свойство соответствующая переменная всегда будет привязана к вставке или обновлению операторов. Это приводит к тому, что вы всегда устанавливаете значение для вашего первичного ключа вручную и игнорируете autoincrement, поскольку

CREATE TABLE mytable ( id integer primary key autoincrement, details varchar(30));
INSERT INTO mytable (id, details) VALUES (0, 'something');

Результаты в этой строке базы данных: 0 | 'something',

Следовательно, это ошибка внутри greendao! Для решения этой проблемы вы можете либо не указывать notNull на вашем столбце первичного ключа или вы можете изменить файл dao.ftl (строка 126ff):

<#list entity.properties as property>
<#if property.notNull || entity.protobuf>
<#if entity.protobuf>
        if(entity.has${property.propertyName?cap_first}()) {
</#if>
<#if property.pkAutoincrement>
        if(entity.get${property.propertyName?cap_first}() != 0) {
</#if>        stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, entity.get${property.propertyName?cap_first}()<#if
     property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()</#if>);
<#if entity.protobuf || property.pkAutoincrement>
    }
</#if>
<#else> <#-- nullable, non-protobuff -->
    ${property.javaType} ${property.propertyName} = entity.get${property.propertyName?cap_first}();
    if (${property.propertyName} != null) {
<#if property.pkAutoincrement>    if (${property.propertyName} != 0) {
    </#if>       stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, ${property.propertyName}<#if property.propertyType == "Boolean"> ? 1l: 0l</#if><#if property.propertyType == "Date">.getTime()    </#if>);
<#if property.pkAutoincrement>        }</#if>
    }
</#if>

Это заставит greendao НЕ связывать ваше значение autoincrement-primarykey с вашими обновлениями или инструкциями вставки, если это не так. != 0 или же null,

Будьте осторожны со вторым подходом: он не проверен и, следовательно, может также иметь побочные эффекты в других частях greendao!

Другие вопросы по тегам