クイックバージョン
基本的に、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:デバッグを介して、データストアに正しい情報があることを確認できます。クエリを実行すると、ダーティ情報が含まれている第2レベルのキャッシュにフォールバックします。データが変更されるたびにキャッシュから削除するのは私次第ではないと思いますか?