我有两个独立的Hibernate
实例在同一台物理机器上的两个不同的jvm中运行。
两个hibernate都使用相同的ehcache.xml
设置文件,而且hibernate jvm都使用了一个公共类:
@Entity
class Parent {
@OneToMany(mappedBy="parent")
@Cache(region = "myCache", usage = CacheConcurrencyStrategy.READ_WRITE)
private List<Children> childrens;
}
指向注意:我使用的是@cache annotation with region defined
。
Ehcache设置xml:
<cache name="myCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="600"
timeToLiveSeconds="6000"
diskExpiryThreadIntervalSeconds="120"
/>
现在,如果处理A
[0]开始交易
[1]读取父对象,然后
[2]读取集合中的所有子节点,这反过来又将子节点对象放入休眠的ehcache的mycache区域,这反过来使内存对象计数为full并且溢出子对象到磁盘并且文件获得已保存在myCahce.data
[3]然后进程A
从集合中删除子对象。
[4]交易完成
另一个进程B
在获取事务时完成msg,读取父对象,如果我们尝试运行parent.getChildren()
,我会得到
org.hibernate.ObjectNotFoundException: No row with the given identifier exists[my.package.class.entity#3218]
这意味着进程B
hibernate确实从某处获得了子对象标识符值,但是当它实际上尝试从db加载对象时它无法找到它。
理想情况下,它不应该有标识符值。
问题
是否发生这种情况是因为hibernate实例最终都使用相同的myCache.data
和diskExpiryThreadIntervalSeconds = 120
,因此文件缓存中的对象在120秒之前不会出现脏标志on
。
因此,进程B
最终从缓存文件中加载集合对象的ids
,但是当它实际上尝试从db加载时,它找不到该行并因此抛出错误?
系统详情:
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.2.2.Final</version>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.2.Final</version>