为什么我在Android下使用OrmLite获取DatabaseObjectNotClosedException?

时间:2012-04-23 20:06:51

标签: java android sqlite ormlite

使用OrmLite开始新的android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here时,我得到Activity

我自己没有使用任何Cursor,所以它必须是ORMLite使用的低级代码。不知道相关代码会在这里,但基本上我通常在事务管理器中使用带有2个Dao对象的Query / DeleteBuilders。导致问题的最小示例(删除了异常处理):

return new TransactionManager(connectionSource).callInTransaction(new Callable<List<ConversionData>>() {
    public List<ConversionData> call() throws Exception {
        QueryBuilder<ConversionData, Date> builder = getDataDao().queryBuilder();
        builder.orderBy("date", /* desc */ true);
        return builder.query();
    }
});

由于Dao和建造者都没有任何接近的方法,我不确定我究竟应该在哪里关闭。

我的Activity中有一个延伸OrmLiteBaseActivity的近距离方法,但是当我从其他活动返回时,我将如何再次打开它?

1 个答案:

答案 0 :(得分:3)

所以经过一些来回,这对于一个未被关闭的惰性集合上的数据迭代器来说是一个问题。 @Voo正在做类似以下的事情:

for (ConversionRate rate : conversionRates) { 
    if (rate.getCurrency().equals(curr)) 
        // you can't do this because otherwise the iterator won't be closed
        return rate; 
}

这个问题曾经发生过一次。 documentation for iterators明确了解它。引用:

  

注意:您必须翻阅迭代器的所有项以关闭基础SQL对象。如果你没有全力以赴,垃圾收集器将在一段时间后关闭SQL语句,这被认为是错误的形式。请参阅下面的包装迭代。

还记录了lazy collections的问题:

  

警告:因为我们需要小心关闭迭代器,所以不应该在这里使用(;;)循环。

要调试此问题,我们首先将延迟加载的集合转换为具有@ForeignCollection(eager = true)的急切集合。这消除了问题,表明它可能是for循环或其他一些不良模式的不正确中断。

其他人的好教训。