I have a test case that isolates a caching problem I am experiencing.
1. I use a query (setCacheable==true) to retieve a
BillingMethod object from the database, for which I see the SQL query hit the DB.
2. I re-execute the same query and it retrieves the object from the cache. No SQL query is issued to the DB.
3. I use
session.load() to retieve the object from the object cache without hitting the DB.
4. I then retrieve the object using
session.load(), modify it and save it to the DB.
From that point on,
all queries used to retrieve the same object from the database result in hits to the DB, and the query cache no longer works. I can however, use
session.load() to reteieve the object without hitting the DB.
How, do I ensure that step #1 and #2 continue to behave the same way after updating the object in step #4?
Any advice would be greatly appreciated.
Thanks!
-Erik
Hibernate version: 3.2.3
Database: MySQL 5.0.41
OS: Mac OS X 10.4.10
Code snippet:
Code:
void printBillingMethods(Session session) {
Transaction tx = session.beginTransaction();
tx = session.beginTransaction();
Query q = session.createQuery("FROM BillingMethod where id=12");
q.setCacheable(true);
List l = q.list();
session.flush();
HashSet<BillingMethod> bMethods = new HashSet<BillingMethod>();
for (Object ch: l) {
bMethods.add((BillingMethod)ch);
}
tx.commit();
for (BillingMethod bm: bMethods) {
System.out.println("Found:" + bm.getName()+" Desc: "+bm.getComment());
}
System.out.println("");
}
void printBillingMethodFromObjectCache(Session session) {
BillingMethod bm = (BillingMethod) session.load(BillingMethod.class, new Long(12));
System.out.println("Found:" + bm.getName()+" Desc: "+bm.getComment()+" in object cache");
System.out.println("");
}
void updateBillingMethod(Session session) {
Transaction tx = session.beginTransaction();
BillingMethod bm = (BillingMethod) session.load(BillingMethod.class, new Long(12));
System.out.println("Updating :" + bm.getName());
bm.setComment(bm.getComment() + "_modified");
session.save(bm);
session.flush();
tx.commit();
System.out.println("Object:" + bm.getName()+" description changed to: "+bm.getComment());
System.out.println("");
}
public static void main(String[] args) {
try {
SessionFactory factory;
try {
java.net.URL url = QueryCacheTest.class.getResource("/hibernate_standalone.cfg.xml");
Configuration cfg = new Configuration().configure(url);
factory = (SessionFactory)cfg.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
Session session = factory.openSession();
QueryCacheTest test = new QueryCacheTest();
test.printBillingMethods(session);
test.printBillingMethods(session);
test.printBillingMethodFromObjectCache(session);
test.updateBillingMethod(session);
test.printBillingMethods(session);
test.printBillingMethodFromObjectCache(session);
session.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Log output snippet:Code:
*Step #1 -- Run the initial query; hits the db and caches the result
11:30:21,662 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,663 DEBUG AbstractConcurrentReadCache:1061 - persistRetrieve called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,663 DEBUG Cache:697 - No cache entry exists for key='sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache', creating
11:30:21,667 DEBUG SQL:401 - select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
Hibernate: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
11:30:21,683 DEBUG AbstractConcurrentReadCache:694 - get called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,683 DEBUG AbstractConcurrentReadCache:1061 - persistRetrieve called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,685 DEBUG Cache:697 - No cache entry exists for key='com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod', creating
11:30:21,685 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,685 DEBUG AbstractConcurrentReadCache:1087 - persistRetrieveGroup called (groupName=com.meltwater.admin.orm.BillingMethod)
11:30:21,686 DEBUG AbstractConcurrentReadCache:1127 - persistStoreGroup called (groupName=com.meltwater.admin.orm.BillingMethod)
11:30:21,687 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,687 DEBUG AbstractConcurrentReadCache:1061 - persistRetrieve called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,687 DEBUG Cache:697 - No cache entry exists for key='sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache', creating
11:30:21,687 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,687 DEBUG AbstractConcurrentReadCache:1087 - persistRetrieveGroup called (groupName=org.hibernate.cache.StandardQueryCache)
11:30:21,688 DEBUG AbstractConcurrentReadCache:1127 - persistStoreGroup called (groupName=org.hibernate.cache.StandardQueryCache)
Found:Austria Desc: test
* Step #2 -- Re-execute the query to retrieve the object; No SQL query issued
11:30:21,694 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,694 DEBUG AbstractConcurrentReadCache:694 - get called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,694 DEBUG AbstractConcurrentReadCache:1061 - persistRetrieve called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,694 DEBUG Cache:697 - No cache entry exists for key='billingMethod.org.hibernate.cache.UpdateTimestampsCache', creating
Found:Austria Desc: test
* Step #3 -- Retrieve the object via session.load(); No SQL query issued
Found:Austria Desc: test in object cache
* Step #4 -- Retieve the object via session.load(), modify it and save. SQL query issued to update the DB.
Updating :Austria
11:30:21,700 DEBUG AbstractConcurrentReadCache:694 - get called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,700 DEBUG AbstractConcurrentReadCache:1061 - persistRetrieve called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,702 DEBUG Cache:697 - No cache entry exists for key='billingMethod.org.hibernate.cache.UpdateTimestampsCache', creating
11:30:21,702 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,702 DEBUG AbstractConcurrentReadCache:1087 - persistRetrieveGroup called (groupName=org.hibernate.cache.UpdateTimestampsCache)
11:30:21,702 DEBUG AbstractConcurrentReadCache:1127 - persistStoreGroup called (groupName=org.hibernate.cache.UpdateTimestampsCache)
11:30:21,705 DEBUG SQL:401 - update billingMethod set name=?, countryCode=?, orgnr=?, comment=?, accountNumber=?, companyName=?, companyAddress=? where methodId=?
Hibernate: update billingMethod set name=?, countryCode=?, orgnr=?, comment=?, accountNumber=?, companyName=?, companyAddress=? where methodId=?
11:30:21,706 DEBUG AbstractConcurrentReadCache:694 - get called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,706 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,708 DEBUG AbstractConcurrentReadCache:694 - get called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,708 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=com.meltwater.admin.orm.BillingMethod#12.com.meltwater.admin.orm.BillingMethod)
11:30:21,710 DEBUG AbstractConcurrentReadCache:694 - get called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,711 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
Object:Austria description changed to: test_modified
*Step #1 -- Re-run the query after update; hits the db and caches the result
11:30:21,711 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,712 DEBUG AbstractConcurrentReadCache:694 - get called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,712 DEBUG SQL:401 - select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
Hibernate: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
11:30:21,714 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,714 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
Found:Austria Desc: test_modified
* Step #2 -- Re-execute the query to retrieve the object; SQL query issued! Not retrieved from cache.
11:30:21,715 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,715 DEBUG AbstractConcurrentReadCache:694 - get called (key=billingMethod.org.hibernate.cache.UpdateTimestampsCache)
11:30:21,716 DEBUG SQL:401 - select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
Hibernate: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12
11:30:21,719 DEBUG AbstractConcurrentReadCache:694 - get called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
11:30:21,719 DEBUG AbstractConcurrentReadCache:1108 - persistStore called (key=sql: select billingmet0_.methodId as methodId1_, billingmet0_.name as name1_, billingmet0_.countryCode as countryC3_1_, billingmet0_.orgnr as orgnr1_, billingmet0_.comment as comment1_, billingmet0_.accountNumber as accountN6_1_, billingmet0_.companyName as companyN7_1_, billingmet0_.companyAddress as companyA8_1_ from billingMethod billingmet0_ where billingmet0_.methodId=12; parameters: ; named parameters: {}.org.hibernate.cache.StandardQueryCache)
Found:Austria Desc: test_modified
* Step #3 -- Retrieve the object via session.load(); No SQL query issued
Found:Austria Desc: test_modified in object cache
Hibernate config file snippet:Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Properties -->
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.url">
jdbc:mysql://localhost/magenta
</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="max_fetch_depth">3</property>
<property name="show_sql">true</property>
<property name="cache.provider_class">com.opensymphony.oscache.hibernate.OSCacheProvider</property>
<property name="cache.use_query_cache">true</property>
<mapping resource="com/meltwater/admin/orm/BillingMethod.hbm.xml" />
<class-cache class="com.meltwater.admin.orm.BillingMethod" usage="nonstrict-read-write" />
</session-factory>
</hibernate-configuration>
Mapping config file snippet:Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.meltwater.admin.orm">
<class name="BillingMethod" table="billingMethod">
<id name="id" column="methodId" type="long">
<generator class="native"/>
</id>
<property name="name" type="string" length="50" />
<property name="countryCode" type="string" length="3" />
<property name="orgnr" type="string" length="255" />
<property name="comment" type="text" />
<property name="accountNumber" type="string" length="64" />
<property name="companyName" type="string" length="64" />
<property name="companyAddress" type="string" length="64" />
</class>
</hibernate-mapping>