所以我有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(...)
调用)storeDao
和testDao
也应该引用同一个对象。我在Eclipse调试器中看到了这一点,但是:
此外,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可能来自哪里?
期待格雷的洞察力! : - )
答案 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创建和缓存。它应该解决这个问题。