Быстрая версия
По сути, я обновляю таблицу Hibernate, а последующие запросы загружают устаревшее значение.
Подробная версия
Hibernate (3.3.1.GA) и EhCache (2.4.2).
Постоянный Book
объект с List<PageContent>
страницами, и я добавляю страницу в серединуэта книга.Я использую Databinder / Wicket, хотя я не думаю, что это связано.
public void createPageContent(Book book, int index) {
Databinder.getHibernateSession().lock(book, LockMode.UPGRADE);
PageContent page = new PageContent(book);
book.addPage(page, index);
CwmService.get().flushChanges(); // commits the transaction
}
Применимые поля / метод в Book
:
@OneToMany
@JoinColumn(name="book_id")
@IndexColumn(name="pageNum")
@Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
private List<PageContent> pages = new ArrayList<PageContent>();
public synchronized void addPage(PageContent page, int index) {
pages.add(index, page);
}
Конечный результатчто в список добавлена новая страница, и база данных обновлена соответствующим образом, и я подтвердил это в своем хранилище данных.Однако следующий запрос для страницы, скажем «Страница № 4», загружает «старую» Страницу № 4 вместо новой Страницы № 4:
criteria.add(Restrictions.eq("book", book));
criteria.add(Restrictions.eq("pageNum", pageNum));
criteria.setCacheable(true);
Итак, я неохотно удаляю кэширование из критериев,Он запрашивает хранилище данных, но по-прежнему возвращает неправильное значение .Однако в обоих случаях, если я подожду около 2 минут, все работает как положено.Я предполагаю, что кэширование все еще вовлечено.И PageContent
, и Book
используют эту стратегию кэширования:
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
Признаюсь, я новичок в кэшировании и просто настроил этот файл в первый раз.Вот мой ehcache.xml:
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="false"/>
<!-- Hibernate's Cache for keeping 'lastUpdated' data on each table. Should never expire. -->
<cache name="org.hibernate.cache.UpdateTimestampsCache" eternal="true" />
<!-- Hibernate's Query Cache - should probably be limited -->
<cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="1000" />
ОБНОВЛЕНИЕ : удаление аннотаций @Cache
в моих объектах хранилища данных устраняет проблему.Конечно, я хотел бы кэшировать эти объекты, потому что модификация страницы гораздо реже, чем доступ.
Итак, мысли?Есть еще несколько вопросов, связанных с удалением страниц.Все обновляет базу данных, как и ожидалось, но фактическое поведение шаткое.
Заранее спасибо!
ОБНОВЛЕНИЕ # 2 : С помощью отладки я могу подтвердить, что в хранилище данных естьправильная информация, и когда запрос выполняется, он возвращается к кэшу второго уровня, который содержит грязную информацию.Я полагаю, что я не могу изымать из кэша каждый раз, когда данные изменяются?