基本上,我更新一個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" />
UPDATE:刪除@Cache
註解數據存儲區對象中刪除的問題。當然,我想緩存這些對象,因爲頁面修改比訪問要少得多。
那麼,想法?還有其他幾個相關問題,包括刪除頁面。一切都按預期更新數據庫,但實際行爲不可靠。
在此先感謝!
更新#2:通過調試,我可以確認數據存儲具有正確的信息,並且當查詢運行時,它回退到二級緩存 - 它有髒信息。每當數據發生變化時,我認爲我無法從緩存中逐出?
當您運行條件查詢時,您是否看到正在運行的sql? (logger org.hibernate.sql) – 2011-05-19 20:34:10
是的,我的日誌語句都支持我上面提出的評論。當我查詢緩存時,EhCache在緩存條目上報告了「命中」。當我做了'setCacheable(false)'查詢確實運行。 – jbrookover 2011-05-19 21:25:18
所以接下來的事情是,你確定你期望在數據庫中所做的更改肯定在數據庫中,並且對於另一個連接是可見的? – 2011-05-20 06:04:17