ORMLite OpenHelper Кеширование DAO в DaoManager? - PullRequest
1 голос
/ 14 февраля 2012

Итак, у меня есть собственный подкласс OrmLiteSqliteOpenHelper. Я хочу использовать интерфейс ObjectCache, чтобы убедиться, что у меня есть сопоставление идентификаторов из строк БД в объекты в памяти, поэтому я переопределяю 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:

Different object IDs

Кроме того, кэш объектов testDao равен нулю.

Я что-то здесь не так делаю? Это ошибка?

У меня есть специальный менеджер помощников, но только потому, что мне нужно было управлять несколькими базами данных. Это просто хэш-карта Class<? extends DatabaseHelper> ключей для экземпляров.

Причина, по которой мне нужен мой кешированный DAO, заключается в том, что у меня есть несколько внешних коллекций, которые активно загружаются внутренними сгенерированными DAO, которые не используют мой глобальный кэш и, таким образом, воссоздаются независимо для каждой коллекции.

Когда я писал это, я думал, что могу просто переопределить мой helpy.getDao(...) вызов до DaoManager.createDao(...), но это приводит к тому же самому: я все еще получаю другой DAO при втором вызове createDao(...) , Мне кажется, что это полностью против документов для 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 в строке 230 источника для DaoManager препятствует обновлению classMap (так как я использую предварительно сгенерированные файлы конфигурации?). Когда мой код попадает во второй вызов create, он сначала смотрит на classMap и каким-то образом (вопреки моему лучшему пониманию) находит другую копию DAO, живущую там. Что очень странно, потому что, шагая через первое создание, я наблюдал, как инициализируется classMap.

Но откуда взялся бы второй DAO?

С нетерпением жду понимания Грея! : -)

Ответы [ 2 ]

0 голосов
/ 15 февраля 2012

Как упомянул @Ben, существует некоторое внутреннее создание DAO, которое портит ситуацию, но я думаю, что он, возможно, обнаружил ошибку.

Под Android ORMLite пытается использовать магическое отражение для создания DAO с заданной ужасной отражающей способностью для всех, кроме самых последних версий ОС Android. Всякий раз, когда пользователь запрашивает DAO для класса Store (например), волшебное отражение fu создает один DAO, но внутренне использует другой. Я создал следующую ошибку:

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

Я изменил способ создания DAO, чтобы лучше использовать вывод отражения. Изменения были вытеснены в 4.34. Этот выпуск обновляет (и упрощает) внутреннее создание и кэширование DAO. Это должно решить проблему.

http://ormlite.com/releases/

0 голосов
/ 14 февраля 2012

Шучу. Похоже, что может происходить то, что моя инициализация DAO объекта Store создает DAO для внешних подключений (для которых я установил foreignAutoRefresh), а затем рекурсивно создаю для себя еще один DAO (поскольку начавшееся это создание DAO еще не завершено, и поэтому еще не зарегистрировано DaoManager).

Похоже, это нужно делать с рекурсией, отмеченной в BaseDaoImpl.initialize().

Я вспоминаю начальные воспоминания, просто глядя на это.

...