在DaoManager中使用ORMLite OpenHelper DAO缓存?

时间:2012-02-14 16:37:12

标签: android ormlite

所以我有OrmLiteSqliteOpenHelper的自定义子类。我想使用ObjectCache接口来确保我有从DB行到内存中对象的身份映射,因此我将getDao(...)覆盖为:

@Override
public <D extends Dao<T, ?>, T> D getDao(Class<T> arg0) throws SQLException {
    D dao = super.getDao(arg0);
    if (dao.getObjectCache() == null && !UNCACHED_CLASSES.contains(arg0))   
        dao.setObjectCache(InsightOpenHelperManager.sharedCache());
    return dao;
}

我的理解是super.getDao(Class<T> clazz)基本上是在幕后调用DaoManager.createDao(this.getConnectionSource(),clazz),如果存在的话应该找到一个缓存的DAO。然而...

final DatabaseHelper helpy = CustomOpenHelperManager.getHelper(StoreDatabaseHelper.class);

final CoreDao<Store, Integer> storeDao = helpy.getDao(Store.class);
DaoManager.registerDao(helpy.getConnectionSource(), storeDao);
final Dao<Store,Integer> testDao = DaoManager.createDao(helpy.getConnectionSource(), Store.class);

我希望(即使没有registerDao(...)调用)storeDaotestDao也应该引用同一个对象。我在Eclipse调试器中看到了这一点,但是:

Different object IDs

此外,testDao的对象缓存为空。

我在这里做错了吗?这是一个错误吗?

我确实有一个自定义助手管理器,但仅仅因为我需要管理多个数据库。它只是实例的Class<? extends DatabaseHelper>个键的哈希映射。

我需要缓存DAO的原因是我有几个外来集合,它们都是内部生成的DAO,它们没有使用我的全局缓存,因此正在为每个集合独立地重新创建。

当我写这篇文章的时候,我想我可以让我的helpy.getDao(...)调用DaoManager.createDao(...)来调用createDao(...),但这导致同样的事情:我在第二次调用时仍会得到一个不同的DAO到DaoManager。在我看来,这完全违背了registerDao(...)的文档。

首先,我认为public static synchronized void registerDao(ConnectionSource connectionSource, Dao<?, ?> dao) { if (connectionSource == null) { throw new IllegalArgumentException("connectionSource argument cannot be null"); } if (dao instanceof BaseDaoImpl) { DatabaseTableConfig<?> tableConfig = ((BaseDaoImpl<?, ?>) dao).getTableConfig(); if (tableConfig != null) { tableMap.put(new TableConfigConnectionSource(connectionSource, tableConfig), dao); return; } } classMap.put(new ClassConnectionSource(connectionSource, dao.getDataClass()), dao); } 可能是罪魁祸首:

return

DaoManager源代码行230的classMap会阻止classMap更新(因为我使用的是预生成的配置文件?)。当我的代码点击第二个创建调用时,它首先查看classMap,并以某种方式(违反我的理解)找到生活在那里的DAO的不同副本。这是非常奇怪的,因为通过第一次创建,我看到了{{1}}被初始化。

但第二个DAO可能来自哪里?

期待格雷的洞察力! : - )

2 个答案:

答案 0 :(得分:0)

开玩笑吧。看起来可能发生的事情是我的Store对象DAO初始化正在为外部连接创建DAO(我设置为foreignAutoRefresh)然后以递归方式为自己创建另一个DAO(因为启动它的DAO创建尚未完成,因此尚未注册DaoManager)。

看起来这必须与BaseDaoImpl.initialize()中提到的递归有关。

我只是在看这个时就会收到Inception闪回。

答案 1 :(得分:0)

正如@Ben所提到的那样,有一些内部DAO创建正在搞砸,但我认为他可能已经发现了一个错误。

在Android下,ORMLite尝试使用一些神奇的反射来构建DAO,因为除了最新的Android操作系统版本之外,其他所有版本都具有可怕的反射性能。每当用户要求类Store的DAO时(例如),魔术反射fu就会创建一个DAO,但在内部它正在使用另一个DAO。我创建了以下错误:

  

https://sourceforge.net/tracker/?func=detail&aid=3487674&group_id=297653&atid=1255989

我改变了创建DAO的方式,以便更好地使用反射输出。这些变化在4.34中被推出。此版本改进(并简化)内部DAO创建和缓存。它应该解决这个问题。

  

http://ormlite.com/releases/