Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: cleaning hibernate cache between dao tests

  1. #11
    Join Date
    Oct 2004
    Location
    Stockholm
    Posts
    79

    Default

    Quote Originally Posted by Arthur Loder View Post
    Hey robcos,

    protected void disableSecondLevelCache() {
    this.hibernateTemplate.execute(new HibernateCallback() {
    public Object doInHibernate(Session session) throws HibernateException {
    session.setCacheMode(CacheMode.IGNORE);
    return null;
    }
    });
    }
    This disables the first level cache (you are running on the session object)
    and again, I'm trying to clean the cache, not to disable it. The only solution seems to call sessionFactory.evict() for each of the classes that need are mapped using hibernate. A similar approach can be taken, although.
    /Roberto

  2. #12
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Clarification

    Hi robcos,

    Quote Originally Posted by robcos View Post
    This disables the first level cache (you are running on the session object)
    Actually, from the CacheMode API:

    Controls how the session interacts with the second-level cache and query cache.

    -Arthur Loder

  3. #13
    Join Date
    Oct 2004
    Location
    Stockholm
    Posts
    79

    Default

    Quote Originally Posted by Arthur Loder View Post
    Hi robcos,



    Actually, from the CacheMode API:
    Controls how the session interacts with the second-level cache and query cache.
    -Arthur Loder
    Oh sorry, I missunderstood that. Thanks for pointing it out.

  4. #14
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Updated code

    Hi robcos,

    Here is the original class with an updated disableSecondLevelCache() method so that it clears the cache rather than disabling the Session's use of the cache; it relies on casting the SessionFactory to SessionFactoryImpl:

    Code:
    package org.spring.forum;
    
    import java.util.Collection;
    import java.util.Map;
    
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.cache.Cache;
    import org.hibernate.impl.SessionFactoryImpl;
    import org.springframework.orm.hibernate3.HibernateCallback;
    import org.springframework.orm.hibernate3.HibernateTemplate;
    import org.springframework.test.AbstractTransactionalSpringContextTests;
    
    public abstract class AbstractHibernateCacheClearableTest extends AbstractTransactionalSpringContextTests {
    
        /** Hibernate template to use for disabling second level cache. */
        private HibernateTemplate hibernateTemplate;
        
        /** Whether to disable second level cache; defaults to true. */
        private boolean disableSecondLevelCache = true;
        
        @Override
        protected void onSetUpInTransaction() throws Exception {
            if (this.disableSecondLevelCache) {
                disableSecondLevelCache();
            }
        }
        
        /**
         * Performs the actual disabling of the Hibernate second-level cache.
         */
        protected void disableSecondLevelCache() {
             this.hibernateTemplate.execute(new HibernateCallback() {
                public Object doInHibernate(Session session) throws HibernateException {
                    SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl)session.getSessionFactory();
                    Map cacheRegionsMap = sessionFactoryImpl.getAllSecondLevelCacheRegions();
                    Collection<Cache> cacheRegions = cacheRegionsMap.values();
                    for (Cache cache : cacheRegions) {
                        cache.clear();
                    }
                    return null;
                }
            });     
        }
    
        /**
         * Sets the HibernateTemplate for disabling the Hibernate second-level
         * cache.
         * 
         * @param hibernateTemplate the HibernateTemplate for disabling the
         *            Hibernate second-level cache.
         */
        public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
            this.hibernateTemplate = hibernateTemplate;
        }
    
        /**
         * Sets whether to disable the Hibernate second-level cache. Defaults to
         * true.
         * 
         * @param disableSecondLevelCache whether to disable the Hibernate
         *            second-level cache.
         */
        public void setDisableSecondLevelCache(boolean disableSecondLevelCache) {
            this.disableSecondLevelCache = disableSecondLevelCache;
        }
    
        /**
         * Checks whether disabling of Hibernate second-level cache should occur.
         * Can be overridden by subclasses to return false to allow second-level
         * cache usage (or the disableSecondLevelCache can be set to false, either
         * programmatically or through injection).
         * 
         * @return whether disabling of Hibernate second-level cache should occur.
         */
        public boolean isDisableSecondLevelCache() {
            return this.disableSecondLevelCache;
        }
        
    }
    The above code calls Cache.clear for every cache region. An alternative method implementation that might work is defined below, which retrieves all mapped classes and calls Session.evictEntity for each:

    Code:
    protected void disableSecondLevelCache() {                                                                                                                         
        this.hibernateTemplate.execute(new HibernateCallback() {                                  
            public Object doInHibernate(Session session) throws HibernateException {                 
                SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl)session.getSessionFactory();
                // Every persistent class extends java.lang.Object, so the following call will return all persistent classes
                String[] persistentClasses = sessionFactoryImpl.getImplementors("java.lang.Object");    
                for (String persistentClass : persistentClasses) {                             
                    sessionFactoryImpl.evictEntity(persistentClass);                              
                }                                                                              
                return null;                                                                            
            }                                                                                  
        });                                                                                       
    }
    The relevant APIs are SessionFactoryImpl.getAllSecondLevelCacheRegions and SessionFactoryImpl.getImplementors.

    I hope one of those implementations actually works!

    -Arthur Loder
    Last edited by Arthur Loder; Oct 4th, 2006 at 10:28 AM.

  5. #15
    Join Date
    Oct 2004
    Location
    Stockholm
    Posts
    79

    Default

    Quote Originally Posted by Arthur Loder View Post
    Hi robcos,
    Here is the original class with an updated disableSecondLevelCache() method so that it clears the cache rather than disabling the Session's use of the cache; it relies on casting the SessionFactory to SessionFactoryImpl:
    I like it, thank you!
    Anyway, it is maybe safer to use the interface "SessionFactoryImplementor" instead of the class "SessionFactoryImpl"

    /roberto

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •