I am using hibernate with JBossCache as a second level cache and I see messages like this in the log (my log4j.properties is below):
ERROR [main] (TreeCache.java:2461) - node //test/Item/bids/1 not found
Digging a little, I found that the message is created in the TreeCache._remove if the node being removed does not exist. This situation happens when hibernate tries to evict the same collection more than once from the cache.
I wrote a piece of code that can recreate the error (be careful to set up lo4j properly otherwise you won't see anything.) It is really simple with Item and Bid objects with one-to-many, bi-directional relationship.
What I would like to know is how serious this issue is. Looking at the code is seems that the TreeCache is left at a inconsistent state when the error happen, but I could be wrong.
Code to recreate the problem:
Bid bid = new Bid();
bid.setItem(new Item());
sess1.save(bid);
sess1.save(bid.getItem());
tx.commit();
sess1.close();
// The test itself
Session sess2 = sessionFactory.openSession();
tx = sess2.beginTransaction();
List list = sess2.find("from Item");
Item item = (Item)list.get(0);
// I change the set.
item.getBids().clear();
// flush forced and the collection is evicted from
// the cache
sess2.find("from Bid");
// another change to the same set
item.addToBids(new Bid());
//when the session flushes here, the session
// will evit the collection from the cache
// and this will make jbosscache to
// log an error.
tx.commit();
sess2.close();
Hibernate version:
2.1.7c
JBoss Cache version:
1.2
Mapping documents:
<hibernate-mapping package="test">
<class name="Bid" table="BID">
<id column="id" name="id" type="integer">
<generator class="vm" />
</id>
<many-to-one name="item" column="ITEM_ID" class="Item" outer-join="true"/>
</class>
</hibernate-mapping >
<hibernate-mapping package="test">
<class name="Item" table="ITEM">
<id column="id" name="id" type="integer">
<generator class="vm" />
</id>
<set inverse="true" cascade="all" name="bids" lazy="true">
<key column="ITEM_ID"/>
<one-to-many class="Bid"/>
</set>
</class>
</hibernate-mapping>
Hibernate cfg file
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:hsqldb:.</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password" />
<property name="hibernate.connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="hibernate.dialect">
net.sf.hibernate.dialect.HSQLDialect
</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<property name="cache.provider_class">
net.sf.hibernate.cache.TreeCacheProvider
</property>
<!-- mappings -->
<mapping file="bin/test/Item.hbm" />
<mapping file="bin/test/Bid.hbm" />
<!-- caching -->
<class-cache class="test.Bid" usage="transactional"/>
<class-cache class="test.Item" usage="transactional"/>
<collection-cache collection="test.Item.bids" usage="transactional"/>
</session-factory>
</hibernate-configuration>
TreeCache xml file
<server>
<mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=TreeCache">
<depends>jboss:service=Naming</depends>
<depends>jboss:service=TransactionManager</depends>
<attribute name="CacheMode">LOCAL</attribute>
</mbean>
</server>
log4j.properties
log4j.rootLogger=ERROR, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
Name and version of the database you are using:
Postgress 7.3
MySQL 4.1
HSQL db (the version that comes with Hibernate 2.1.7)
|