快速版本
基本上,我正在更新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);
因此,我勉强从条件中删除了缓存。它查询数据存储,但 仍返回错误的value
。但是,在两种情况下,如果我等待约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
:通过调试,我可以确认数据存储区具有正确的信息,并且当查询运行时,它会退回到具有脏信息的二级缓存中。我想是不是每次数据更改时都要从缓存中逐出?
我发现了问题,但引入了其他问题。
基本上,在修改Book
对象的List<PageContent>
字段时,Hibernate会执行三件事:
Book
和PageContent
pageNum
每个PageContent
对象上的字段Book
从二级缓存中删除对象。这样可以确保后续查询将搜索新对象等。但是:
PageContent
从二级缓存中删除每个重新编号的对象结果,对页面列表的任何查询都将正常运行,但随后将退回到实际数据的陈旧二级缓存值。
我认为这是因为Hibernate认为pageNum
更改不是数据更改,而是后台管理的更改。但是,这就是我要读取和显示的数据。
解决方案是在插入/删除发生后手动刷新每个页面。
问题内容: 我有一堆应聘者,他们有一些或多个工作,每个人都在公司工作,并且使用了一些技能。 坏的ascii艺术如下: 这是我的数据库: 。 。 。 。 这是我对查询的尝试(请注意,我打算将通配符更改为字段名称;我只是想使某些功能生效): HediSql说 查询出了什么问题?我希望从不良的ascii艺术中可以清楚地知道我要达到的目标。 (此外,它对我连接表的顺序是否有任何速度差异?我将担心新的MyS
我正在查询SQL数据库,但由于某些原因,结果项会随机返回。这是我的密码: searchFriendEmailArrayNew是一个电子邮件地址数组,因此当我查询数据库表时,它会使用电子邮件来查找该用户。数组始终保持一致且顺序相同: user1@email.com 查询总是按照这个顺序进行的。 然后,我查询用户的所选字段,在本例中,我查询的是“isriding”字段。此字段是返回true或false
我们使用1.3.5版本创建了一个spring boot项目。我们的应用程序与Mysql数据库交互。我们创建了一组JPA存储库,在其中我们使用了findAll、findOne和其他自定义查询方法。 我们正面临一个随机出现的问题。以下是复制它的步骤: > 使用spring启动应用程序在数据库上启动读取查询。 现在,使用mysql-console手动更改上面读取查询返回的记录的Mysql中的数据。 再次
问题内容: 今天,我写了一个查询,应该返回一个错误。而是返回带有列名和数据类型的值15 。你知道为什么吗? 结果: 问题答案: 您要指定一个常量: 货币常量表示为数字字符串,带有可选的小数点 和可选的货币符号作为前缀 因此moneyselect $15select ¥15`。 正如Jeroen在评论中指出的那样: 因为日元符号(楼)是货币指示器,并且在某些日语本机字符集中,其代码点与ASCII中的
问题内容: 环境 hibernate4.2 ojdbc6-Oracle 11.2.0.3.0 JDBC 4.0 Oracle数据库11g 问题 我们遵循了许多建议,以如下方式配置Hibernate批处理: 我们检查了日志,发现生成的SQL语句已批处理。但是,如果两个事务同时修改相同版本的实体行,则Hibernate将成功提交它们,导致最后提交的事务中的冲突更新丢失(两个事务中都保存了无冲突的数据,