-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: query cache not invalidated when doing INSERT with CMT
PostPosted: Tue Dec 21, 2004 11:38 pm 
Newbie

Joined: Tue Dec 21, 2004 6:08 pm
Posts: 6
Location: Sydney, NSW, Australia
We are at the moment exploring caching with respect to Hibernate. The application
is a collection of stateless session beans, exposed via RMI to various webapps and
SOAP webservices. All value objects are copied into DTO's (data transfer objects)
before being sent to the client layer.

We use CMT, with JBOSS as the transaction manager/appserver and all operations are done transactionally.

We are trialling both JbossCache and Tangosol as cache providers. Initially we enabled only the 2nd-level
cache (and not the query cache), and tested standard CRUD, and everything worked fine - however while this reduced
the load on the database, we wanted to see what the next level of performance gains would
be using the query cache.

For both Tangosol and JbossCache, the cache is configured to run in full transactional mode.
Eventually we might run in a clustered fashion, however all testing has been done locally.

When the query cache was enabled, there was an obvious improvement given that there was
no round-tripping at all to the database. However, as Hibernate In Action indicates
(pg. 290 7.6.3) "Hibernate expires a cached query result set when there is any insert, update,
or delete of any row of a table that appears in the query".

And this is where it gets interesting, on updates and deletes the query cache is indeed invalidated,
however in the case of an insert, the cache is *not* invalidated and hence we continue to see
only the cached result set (until another delete/update occurs). I have verified this with both
Tangosol and JBossCache, both behave the same way, so I don't believe this is an issue with
the cache provider.

I inserted some trace log calls into the net.sf.hibernate.impl.SessionImpl, and traced it down
to around line 946 in the doSave(final Object object,Key key,final ClassPersister persister, final boolean replicate,final boolean useIdentityColumn,final Cascades.CascadingAction cascadeAction, final Object anything) method:
Code:
    log.trace("finally here, last useIdentityColumn check before exec.add(insert): useIdentityColumn: " + useIdentityColumn);
      if (useIdentityColumn) {
         ScheduledIdentityInsertion insert = new ScheduledIdentityInsertion(values, object, persister, this);
         insert.execute();
         if ( insert.hasAfterTransactionCompletion() ) executions.add(insert);
      log.trace("insert.hasAfterTxnComplete: " + insert.hasAfterTransactionCompletion() + ", executions.size(): " + executions.size());
         id = insert.getGeneratedId();
         persister.setIdentifier(object, id);
         key = new Key(id, persister);
         checkUniqueness(key, object);
      }
   

insert.hasAfterTransactionComplete() is returning false, and hence the insert is not being
added to the executions list, and this is the list that is scanned to decide what
query caches need to be invalidated in the afterTransactionCompletion(boolean success) method.

I presume without better knowledge of how Hibernate exactly handles transaction demarcation
within CMT stateless session bean method calls, that because on an insert an ID needs to be
generated that this puts the doSave method call in a different running context from updates
and deletes which are simpler lightweight calls to the db - and hence are correctly flagged
as tx complete and ready for cache invalidation.

Any ideas on whether this is just a case of misconfiguration somewhere or is there a slight
logic hole when using CMT around inserts in terms of how the hook for query cache invalidation
is implemented?


Hibernate version:
Hibernate 2.1.7, JBoss 3.2.6, JBossCache 1.2, Tangosol Coherence Cache 2.5 Build 290 Eval.

MySQL 4.1.7, MySQL JDBC 3.0.14production & 3.1.5gamma

Mapping documents:
<?xml version="1.0"?>

StatusEvent.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">


<hibernate-mapping>
<class name="x.x.x.StatusEvent" table="StatusEvent">
<cache usage="transactional"/>
<id name="id">
<generator class="native"/>
</id>
<version name="version"/>
<property name="description"/>
<property name="realmId" />
</class>
</hibernate-mapping>

jboss-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="net.sf.hibernate.jmx.HibernateService" name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=DefaultDS</depends>
<attribute name="MapResources">
x/x/x/StatusEvent.hbm.xml
</attribute>
<attribute name="JndiName">java:/hibernate/HibernateFactory</attribute>
<attribute name="Datasource">java:/DefaultDS</attribute>
<attribute name="Dialect">net.sf.hibernate.dialect.MySQLDialect</attribute>
<attribute name="TransactionStrategy">net.sf.hibernate.transaction.JTATransactionFactory</attribute>
<attribute name="TransactionManagerLookupStrategy">net.sf.hibernate.transaction.JBossTransactionManagerLookup</attribute>
<!-- <attribute name="UseOuterJoin">true</attribute> 2.1.4 -->
<attribute name="MaximumFetchDepth">3</attribute> <!-- 2.1.7c -->
<attribute name="ShowSql">false</attribute>
<attribute name="UserTransactionName">UserTransaction</attribute>
<!-- <attribute name="CacheProvider">net.sf.hibernate.cache.TreeCacheProvider</attribute> JbossCache -->
<attribute name="CacheProvider">x.x.x.x.util.TangosolCacheProvider</attribute> <!-- Tangosol Coherence Cache -->
<attribute name="QueryCacheEnabled">true</attribute> <!-- 2.1.7c -->
<!-- <attribute name="UseQueryCache">true</attribute> 2.1.4 -->
</mbean>
</server>

there is no centralised hibernate config file.

mysql ds:

<datasources>
<local-tx-datasource>
<jndi-name>DefaultDS</jndi-name>
<connection-url>jdbc:mysql://localhost/db?autoReconnect=true</connection-url>
<driver-class>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</driver-class>
<check-valid-connection-sql>select 1</check-valid-connection-sql>
<min-pool-size>5</min-pool-size>
<max-pool-size>30</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>300</idle-timeout-minutes>
<track-statements/>
<security-domain>MySqlDbRealm</security-domain>
</local-tx-datasource>
</datasources>

ejb-jar.xml
<session >
<description><![CDATA[]]></description>
<display-name>StatusEvent Services EJB</display-name>

<ejb-name>StatusEventServices</ejb-name>

<home>x.x.x.x.StatusEventServicesHome</home>
<remote>x.x.x.x.StatusEventServices</remote>
<local-home>x.x.x.x.StatusEventServicesLocalHome</local-home>
<local>x.x.x.x.StatusEventServicesLocal</local>
<ejb-class>x.x.x.x.StatusEventServicesBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>

<security-identity>
<use-caller-identity />
</security-identity>

</session>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Local</method-intf>
<method-name>save</method-name>
<method-params>
<method-param>x.x.x.x.StatusEventDTO</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Remote</method-intf>
<method-name>save</method-name>
<method-params>
<method-param>x.x.x.x.StatusEventDTO</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Local</method-intf>
<method-name>update</method-name>
<method-params>
<method-param>x.x.x.x.StatusEventDTO</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Remote</method-intf>
<method-name>update</method-name>
<method-params>
<method-param>x.x.x.x.StatusEventDTO</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Local</method-intf>
<method-name>findAll</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction >
<method >
<ejb-name>StatusEventServices</ejb-name>
<method-intf>Remote</method-intf>
<method-name>findAll</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>

jboss server log on startup:

09:37:04,823 INFO [HibernateServiceMBean] starting service at JNDI name: java:/hibernate/HibernateF
actory
09:37:04,823 INFO [HibernateServiceMBean] service properties: {hibernate.cache.provider_class=x.x.x
.x.util.TangosolCacheProvider, hibernate.transaction.manager_lookup_class=net.sf.hiber
nate.transaction.JBossTransactionManagerLookup, hibernate.cache.use_query_cache=true, hibernate.dial
ect=net.sf.hibernate.dialect.MySQLDialect, hibernate.max_fetch_depth=3, hibernate.session_factory_na
me=java:/hibernate/HibernateFactory, hibernate.connection.datasource=java:/DefaultDS, jta.UserTransa
ction=UserTransaction, hibernate.show_sql=false, hibernate.transaction.factory_class=net.sf.hibernat
e.transaction.JTATransactionFactory}
09:37:04,863 INFO [Environment] Hibernate 2.1.7
09:37:04,863 INFO [Environment] hibernate.properties not found
09:37:04,873 INFO [Environment] using CGLIB reflection optimizer
09:37:04,873 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling
09:37:04,883 INFO [Configuration] Mapping resource: x/x/x/x/StatusEvent.hbm.xml
09:37:05,094 INFO [Binder] Mapping class: x.x.x.x.StatusEvent -> StatusEvent
09:39:15,812 INFO [Configuration] processing one-to-one association property references
09:39:15,812 INFO [Configuration] processing foreign key constraints
09:39:15,912 INFO [Dialect] Using dialect: net.sf.hibernate.dialect.MySQLDialect
09:39:15,942 INFO [SettingsFactory] Maximim outer join fetch depth: 3
09:39:15,952 INFO [SettingsFactory] Use outer join fetching: true
09:39:15,972 INFO [NamingHelper] JNDI InitialContext properties:{}
09:39:15,982 INFO [DatasourceConnectionProvider] Using datasource: java:/DefaultDS
09:39:15,992 INFO [TransactionFactoryFactory] Transaction strategy: net.sf.hibernate.transaction.JT
ATransactionFactory
09:39:16,022 INFO [NamingHelper] JNDI InitialContext properties:{}
09:39:16,032 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: net.sf.
hibernate.transaction.JBossTransactionManagerLookup
09:39:16,052 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup
09:39:16,052 INFO [NamingHelper] JNDI InitialContext properties:{}
09:39:16,062 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: net.sf.
hibernate.transaction.JBossTransactionManagerLookup
09:39:16,072 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup
09:39:16,122 INFO [SettingsFactory] Use scrollable result sets: true
09:39:16,122 INFO [SettingsFactory] Use JDBC3 getGeneratedKeys(): true
09:39:16,122 INFO [SettingsFactory] Optimize cache for minimal puts: false
09:39:16,142 INFO [SettingsFactory] Query language substitutions: {}
09:39:16,142 INFO [SettingsFactory] cache provider: x.x.x.x.util.TangosolCacheProvide
r
09:39:16,172 INFO [SettingsFactory] query cache factory: net.sf.hibernate.cache.StandardQueryCacheF
actory
09:39:16,192 INFO [Configuration] instantiating and configuring caches
09:39:16,463 INFO [STDOUT]
******************************************************************************
*
* Tangosol Coherence(tm): Enterprise Edition is licensed by Tangosol, Inc.
* License details are available at: http://www.tangosol.com/license.jsp
*
* Licensed for evaluation use with the following restrictions:
*
* Effective Date : 15 Nov 2004 00:00:00 GMT
* Termination Date : 15 Jan 2005 00:00:00 GMT
*
* A production license is required for production use.
*
* Copyright (c) 2000-2004 Tangosol, Inc.
*
******************************************************************************
09:39:17,114 INFO [STDOUT]
Tangosol Coherence Version 2.5/290
09:39:32,786 INFO [TangosolCacheProvider] TangosolCacheProvider: buildCache: x.x.x.x.StatusEvent
09:39:33,317 INFO [SessionFactoryImpl] building session factory
09:39:38,985 INFO [SessionFactoryObjectFactory] Factory name: java:/hibernate/HibernateFactory
09:39:39,015 INFO [NamingHelper] JNDI InitialContext properties:{}
09:39:39,045 INFO [NamingHelper] Creating subcontext: hibernate
09:39:39,085 INFO [SessionFactoryObjectFactory] Bound factory to JNDI name: java:/hibernate/Hiberna
teFactory
09:39:39,145 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext
09:39:39,185 INFO [NamingHelper] JNDI InitialContext properties:{}
09:39:39,215 INFO [UpdateTimestampsCache] starting update timestamps cache at region: net.sf.hibern
ate.cache.UpdateTimestampsCache
09:39:39,285 INFO [TangosolCacheProvider] TangosolCacheProvider: buildCache: net.sf.hibernate.cache.Up
dateTimestampsCache
09:39:39,356 INFO [StandardQueryCache] starting query cache at region: net.sf.hibernate.cache.Stand
ardQueryCache
09:39:39,426 INFO [TangosolCacheProvider] TangosolCacheProvider: buildCache: net.sf.hibernate.cache.St
andardQueryCache

Code between sessionFactory.openSession() and session.close():
this is some of the CRUD methods in the DAO..
Code:
   public static void save(StatusEvent event)
         throws HibernateException
   {
       
        Session session = sessions.openSession();
           session.save(event);
         session.flush();
            session.close();       
       
       
   }

   public static void update(StatusEvent event)
         throws HibernateException
   {
             Session session = sessions.openSession();
           session.update(event);
         session.flush();
            session.close(); 
   }

   public static List findAll(Long realmId)
         throws HibernateException
   {
            Session session = sessions.openSession();
            try {
           Query q = session.createQuery("from x.x.x.StatusEvent as n where n.realmId = :id");
           q.setCacheable(true);
           q.setLong("id", realmId.longValue());
          
           return q.list();
        } finally {
           session.close();
        }
   }


Debug level Hibernate log excerpt:

2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) opened session
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) saveWithGeneratedIdentifier id: null:false, short_circuit:false, idenity_column true, id
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) saveWithGeneratedIdentifier: Identity column doSave
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) saving [x.x.x.x.StatusEvent#<null>], useIdentityColumntrue
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) executing insertions
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.engine.Versioning] (RMI TCP Connection(14)-127.0.0.1:) using initial version: 0
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) finally here, last useIdentityColumn check before exec.add(insert): useIdentityColumn: true
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.persister.EntityPersister] (RMI TCP Connection(14)-127.0.0.1:) Inserting entity: x.x.x.x.StatusEvent (native id)
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.persister.EntityPersister] (RMI TCP Connection(14)-127.0.0.1:) Version: 0
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.BatcherImpl] (RMI TCP Connection(14)-127.0.0.1:) about to open: 0 open PreparedStatements, 0 open ResultSets
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.SQL] (RMI TCP Connection(14)-127.0.0.1:) insert into NetworkStatusEvent (version, description, realmId) values (?, ?, ?)
2004-12-22 14:04:18,555 725814 DEBUG [net.sf.hibernate.impl.BatcherImpl] (RMI TCP Connection(14)-127.0.0.1:) preparing statement
2004-12-22 14:04:18,565 725824 DEBUG [net.sf.hibernate.persister.EntityPersister] (RMI TCP Connection(14)-127.0.0.1:) Dehydrating entity: [x.x.x.x.StatusEvent#<null>]
2004-12-22 14:04:18,565 725824 DEBUG [net.sf.hibernate.type.IntegerType] (RMI TCP Connection(14)-127.0.0.1:) binding '0' to parameter: 1
2004-12-22 14:04:18,565 725824 DEBUG [net.sf.hibernate.type.StringType] (RMI TCP Connection(14)-127.0.0.1:) binding 'test msg 30' to parameter: 2
2004-12-22 14:04:18,565 725824 DEBUG [net.sf.hibernate.type.LongType] (RMI TCP Connection(14)-127.0.0.1:) binding '3' to parameter: 3
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.persister.AbstractEntityPersister] (RMI TCP Connection(14)-127.0.0.1:) Natively generated identity: 30
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.BatcherImpl] (RMI TCP Connection(14)-127.0.0.1:) done closing: 0 open PreparedStatements, 0 open ResultSets
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.BatcherImpl] (RMI TCP Connection(14)-127.0.0.1:) closing statement
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) insert.hasAfterTxnComplete: false, executions.size(): 0
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) flushing session
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) Flushing entities and processing referenced collections
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) Processing unreferenced collections
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) Scheduling collection removes/(re)creates/updates
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.Printer] (RMI TCP Connection(14)-127.0.0.1:) listing entities:
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.Printer] (RMI TCP Connection(14)-127.0.0.1:) x.x.x.x.StatusEvent{realmId=3, description=test msg 30, id=30, version=0}
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) executing flush
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) post flush
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) closing session
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) disconnecting session
2004-12-22 14:04:18,575 725834 DEBUG [net.sf.hibernate.engine.CacheSynchronization] (RMI TCP Connection(14)-127.0.0.1:) transaction before completion callback
2004-12-22 14:04:18,605 725864 DEBUG [net.sf.hibernate.engine.CacheSynchronization] (RMI TCP Connection(14)-127.0.0.1:) transaction after completion callback, status: 3
2004-12-22 14:04:18,605 725864 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) transaction completion
2004-12-22 14:04:18,605 725864 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) afterTransactionCompletion: execustions.size():0, invalidateQueryCache:true
.
.
.
then the retrieval of status events

2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) find: from x.x.x.x.StatusEvent as n where n.realmId = :id
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.engine.QueryParameters] (RMI TCP Connection(14)-127.0.0.1:) named parameters: {id=3}
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.hql.QueryTranslator] (RMI TCP Connection(14)-127.0.0.1:) HQL: from x.x.x.x.StatusEvent as n where n.realmId = :id
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.hql.QueryTranslator] (RMI TCP Connection(14)-127.0.0.1:) SQL: select sta0_.id as id, sta0_.version as version, sta0_.description as descript3_, sta0_.realmId as Re9_ from StatusEvent sta0_ where (sta0_.realmId=? )
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.cache.StandardQueryCache] (RMI TCP Connection(14)-127.0.0.1:) checking cached query results in region: net.sf.hibernate.cache.StandardQueryCache
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.cache.StandardQueryCache] (RMI TCP Connection(14)-127.0.0.1:) Checking query spaces for up-to-dateness [[StatusEvent]]
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.cache.StandardQueryCache] (RMI TCP Connection(14)-127.0.0.1:) returning cached query results
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) loading [x.x.x.x.StatusEvent#6]
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) attempting to resolve [x.x.x.x.StatusEvent#6]
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.cache.TransactionalCache] (RMI TCP Connection(14)-127.0.0.1:) cache lookup: 6
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.cache.TransactionalCache] (RMI TCP Connection(14)-127.0.0.1:) cache hit
2004-12-22 14:04:18,855 726114 DEBUG [net.sf.hibernate.impl.SessionImpl] (RMI TCP Connection(14)-127.0.0.1:) resolved object in second-level cache [x.x.x.x.StatusEvent#6]
.
.
.
continues to load the other status events in realm 3.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 22, 2004 4:26 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Tip: post this in our Hibernate with JBoss and JBoss cache forum....more likely the right people will see it..

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: occurs under Hibernate 3.0 as well
PostPosted: Thu Dec 23, 2004 9:47 pm 
Newbie

Joined: Tue Dec 21, 2004 6:08 pm
Posts: 6
Location: Sydney, NSW, Australia
I've tested it under Hibernate 3.0, and this is still an issue.

However, switching from a generator class of native to assigned eliminates the issue, and the cache is correctly invalidated.

This seems to confirm my initial suspicion that the issue lies in the identity generation.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 06, 2005 5:49 pm 
Newbie

Joined: Thu Jan 06, 2005 4:41 pm
Posts: 8
I have exactly the same problem and traced it down to the same peice of code.

My setup is Hibernate 2.1.7, JBoss 3.2.4 and Microsoft SQL Server 2000.

I have tried to do an update just after the save but the data is not dirty so no actual update is done which means no invalidation.

I finally found that invalidating the data myself is the only solution that works. Fortunatly, all my hibernate access is hidden behind a DAO pattern so it is quite easy to do.

code looks like this:
SessionImpl sessionImpl = (SessionImpl) session;
((SessionFactoryImpl)sessionImpl.getSessionFactory()).getUpdateTimestampsCache().invalidate(space);

Sad part is that i have to hardcode the table names in my code and that invalidation is not done in cascade but only on root objects. Hopefully the latter wont cause any problem.

So if anyone has a cleaner workaround (or a fix ;-), I would appreciate it.

Thanks,
Nicolas Fournier


Top
 Profile  
 
 Post subject: is this safe?
PostPosted: Thu Jan 06, 2005 6:06 pm 
Newbie

Joined: Tue Dec 21, 2004 6:08 pm
Posts: 6
Location: Sydney, NSW, Australia
How do you gurantee repeatable read transaction isolation level if you have to manually invalidate the query cache?

are you invalidating inside the transaction block of the insert? or outside, after the session close?

in either case, its not clear if using query cache maintains repeatable read, I assume it does, given there are no warnings in the documentation - however I would hazard a guess that manually invalidating the cache is likely to be unsafe unless you're absolutely sure about the concurrency issues that it raises.

I will raise a bug for this however, given that at least one other person can reproduce this!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 06, 2005 8:36 pm 
Newbie

Joined: Thu Jan 06, 2005 4:41 pm
Posts: 8
I am doing this inside the scope of the session. I don't think there will be any problems because I only do this at object creation (session.save()) as the others (update/delete) already work. AFAIK, a repeatable read problem would only occur with concurent updates/reads.

I was thinking of filling a bug report myself but now that you did, I just have to wait it's fixed ;-)

Can you share the bug number so that I can vote ?

Thanks.


Top
 Profile  
 
 Post subject: i haven't raised the bug yet
PostPosted: Thu Jan 06, 2005 9:19 pm 
Newbie

Joined: Tue Dec 21, 2004 6:08 pm
Posts: 6
Location: Sydney, NSW, Australia
if you have already packaged up the bug, you should submit, because for us, we are only at the moment investigating hibernate caching, and as such not a very high priority. It will take me sometime to create the bug report and testcase.

Concurrency is still an issue, a query for all results occuring at the same time as an insert, if the query cache is invalidated just before the insert goes through (which is what you're doing), the result for the all-result query will be recached *before* the insert, but after cache invalidation - thereby leaving you with the same problem, stale cache.


Top
 Profile  
 
 Post subject: bug HB-1380 raised - please vote!
PostPosted: Fri Jan 07, 2005 1:05 am 
Newbie

Joined: Tue Dec 21, 2004 6:08 pm
Posts: 6
Location: Sydney, NSW, Australia
who does this affect? Basically anyone using MySQL + Hibernate, and wants to improve performance by significantly reducing db traffic (2nd level cache still results in hits to db, only query caching prevents a hit to the db)

here's the url, its a quick rego:

http://opensource.atlassian.com/project ... fault.jspa

and then vote for HB-1380 here:

http://opensource.atlassian.com/project ... se/HB-1380


thanks!
Jason


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 09, 2005 8:39 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
This is a dupe of the already-fixed HB-1362.

http://opensource.atlassian.com/project ... se/HB-1362


By the way, I do not believe it affects 3.0 beta 1, and I have a unit test to prove it. I'm sure you are mistaken on that.

Please use current CVS of Hibernate2 if this bug affects you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.