首先,hibernate中的二级缓存分2块,第一块是modal的class中设置,第二块是set中设置,根据测试来看,缓存在set中的内容并非是整个子对象的set,而是子对象的ID的set集合,因此当子对象有变动时候,缓存中set里该子对象拿出来也会更新,而当子对象自己删除并没有通知到主对象的时候就会发生缓存不同步的问题,也就是主对象的set中还存在子对象的ID,但是子对象实际已经删除了,这个时候hibernate会报缓存找不到子对象的错误,因此遇到这种情况,在处理子对象之前必须把主对象set中该子对象remove掉,这样缓存就同步了。
再放一个hbm.xml例子吧,这里的主对象就是Month,子对象是Thing。set是Thing的集合。如果开启了hibernate二级缓存后只删除了子对象某Thing,而不去在该Thing的Month对象的Set集合中把自己给remove掉就会出现上面描述的错误。
解决方法就是在删除该Thing前去取下该Thing的Month对象下的Set集合,把这个集合中该Thing对象reomve后再删除该Thing。
PS:要用二级缓存必须在class和set中加入<cache>标签
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.myweb.modal.hibernate"> <class name="Month" table="month" catalog="myweb"> <cache usage="nonstrict-read-write" region="Month"/> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="20" not-null="true" /> </property> <property name="total" type="java.lang.Float"> <column name="total"/> </property> <many-to-one name="creater" column="creater_id" class="Creater" cascade="all" unique="true"></many-to-one> <set name="things" inverse="true" lazy="false" cascade="all-delete-orphan"> <cache usage="nonstrict-read-write" region="Month.things"/> <key column="monthid"/> <one-to-many class="Thing"/> </set> </class> </hibernate-mapping>