插入房间中的多对多关系

时间:2018-06-21 09:50:39

标签: android sql android-asynctask many-to-many android-room

我目前正在构建一个android应用程序,该应用程序使用一个小型数据库,该数据库由两个实体数据类(Card和CardDeck)组成,而第三个数据库则通过映射长id primary来代表前两个实体之间的多对多关系键(CardInCardDeckRelation)。

现在,我想在数据库中插入一个新的Deck,这很好,但是如果以后我想使用insertCardDeck()方法返回的id插入一些CardInCardDeckRelation-objects,它会失败,因为插入调用关系表在完成cardDeck对象的插入之前发生,所以我总是得到错误的cardDeck-id。

我认为我通过使用异步任务插入CardDeck朝着正确的方向前进,但是我不知道从那里继续,因为我只能将一组参数传递给我的异步任务对象,所以我无法传递我要插入的Relationshipobject,例如Async-task-class中的onPostExecute方法。

这是我的存储库类中的插入方法:

public void insertCardDeckAsync(CardDeck cardDeck){
    new insertAsyncTaskDao(mCardDeckDao).execute(cardDeck);
}

private static class insertAsyncTaskDao extends AsyncTask<CardDeck, Void, Void> {

    private CardDeckDao mAsyncTaskDao;

    insertAsyncTaskDao(CardDeckDao dao){
        mAsyncTaskDao = dao;
    }

    @Override
    protected Void doInBackground(final CardDeck... params){
        mAsyncTaskDao.insertCardDeck(params[0]);
        return null;
    }

    @Override
    protected void onPostExecute(Void v){
        //maybe insert Relationship object here?
    }
}

如果有人可以提供一种方法,可以使用先前插入的对象生成的ID在以后正确插入实体对象和一些多对多关系对象,我将非常感激。

1 个答案:

答案 0 :(得分:0)

因此,经过一些测试,我发现了我的错误:
我最初使用的是Executor,该Executor是在App的其他位置定义的,用于处理数据库操作,因此不必创建扩展AsyncTask的私有内部类对于我的Repository类中的每个数据库操作。
出于某种原因,尽管我使用Executor似乎在执行数据库查询时确实阻塞了特定线程,所以:

mExecutors.diskIO().execute(new Runnable(){
    //insert new Deck

    //insert Many-to-Many relationsship-object
}

将立即接连执行这两个操作,从而导致与SQL-ForeignConstraint相关的错误,因为它试图在插入实际的Deck对象之前插入Realtion对象。

解决方案是仅使用AsyncTask,以doInBackground-method中正确的顺序处理所有数据库操作:

@Override
    protected Void doInBackground(final CardDeck... params){
        // insert new deck object into database
        insertionId = mAsyncTaskDao.insertCardDeck(params[0]);

        // create relations-array
        CardInCardDeckRelation[] relations = new CardInCardDeckRelation[STANDARD_CARDS.length];

        // insert standard-card objects into array
        for(int i = 0; i < STANDARD_CARDS.length; i++){
            relations[i] = new CardInCardDeckRelation(insertionId,
                    mAsyncCardDao.getStandardCardByName(STANDARD_CARDS[i]),
                    i);
        }

        // insert created array into database
        mRelationDao.insertMultiple(relations);
        Log.d(LOG_TAG, "Deck inserted");
        return null;
    }

如果有人需要进一步的说明,我可以提供整个AsyncTask类。