基本上,我更新一个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