Нет улучшения скорости при использовании Ehcache с Hibernate.

Я не получаю улучшения в скорости при использовании Ehcache с Hibernate

Вот результаты, которые я получаю, когда запускаю тест ниже. Тест считывает 80 объектов Stop, а затем снова те же 80 объектов Stop с использованием кеша.

При втором чтении он попадает в кеш, но улучшения скорости нет. Любая идея о том, что я делаю неправильно?

Speed Test:

First Read: Reading stops 1-80 : 288ms
Second Read: Reading stops 1-80 : 275ms

Cache Info:

elementsInMemory: 79
elementsInMemoryStore: 79
elementsInDiskStore: 0

JunitCacheTest

public class JunitCacheTest extends TestCase  {

    static Cache stopCache;

    public void testCache()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-hibernate.xml");
        StopDao stopDao = (StopDao) context.getBean("stopDao");

        CacheManager manager = new CacheManager();
        stopCache = (Cache) manager.getCache("ie.dataStructure.Stop.Stop");
        //First Read
        for (int i=1; i<80;i++)
        {
            Stop toStop = stopDao.findById(i);
        }
        //Second Read
        for (int i=1; i<80;i++)
        {
            Stop toStop = stopDao.findById(i);
        }


        System.out.println("elementsInMemory " + stopCache.getSize());
        System.out.println("elementsInMemoryStore " + stopCache.getMemoryStoreSize());
        System.out.println("elementsInDiskStore " + stopCache.getDiskStoreSize());

    }

        public static Cache getStopCache() {
        return stopCache;
    }
}

HibernateStopDao

    @Repository("stopDao")
    public class HibernateStopDao implements StopDao {

        private SessionFactory sessionFactory;

        @Transactional(readOnly = true)
        public Stop findById(int stopId) {

            Cache stopCache = JunitCacheTest.getStopCache();
            Element cacheResult = stopCache.get(stopId);

            if (cacheResult != null){

                return (Stop) cacheResult.getValue();
            }
            else{

                Stop result =(Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
                Element element = new Element(result.getStopID(),result);
                stopCache.put(element);
                return result;
            }
        }
    }

ehcache.xml

   <cache name="ie.dataStructure.Stop.Stop"
    maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="5200"
    timeToLiveSeconds="5200"
    overflowToDisk="true">
    </cache>

стоп.hbm.xml

    <class name="ie.dataStructure.Stop.Stop" table="stops" catalog="hibernate3" mutable="false" >
     <cache usage="read-only"/>
            <comment></comment>
            <id name="stopID" type="int">

                <column name="STOPID" />
                <generator class="assigned" />
            </id>
            <property name="coordinateID" type="int">
                <column name="COORDINATEID" not-null="true">
                    <comment></comment>
                </column>
            </property>
            <property name="routeID" type="int">
                <column name="ROUTEID" not-null="true">
                    <comment></comment>
                </column>
            </property>
        </class>

Останавливаться

public class Stop implements Comparable<Stop>, Serializable  {

    private static final long serialVersionUID = 7823769092342311103L;
    private Integer stopID;
    private int routeID;
    private int coordinateID;
    }

person patrick-fitzgerald    schedule 16.05.2010    source источник


Ответы (2)


Первая ошибка, которую я вижу, заключается в том, что вы обрабатываете кеш поверх кеша второго уровня Hibernate, который уже будет кэшировать Stop объектов. Это просто бесполезно, кеш второго уровня прозрачен, вам не нужно добавлять дополнительные классы (например, Element здесь) или дополнительный код. Таким образом, метод DAO должен быть:

@Transactional(readOnly = true)
public Stop findById(int stopId) {
    return (Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
}

И все, больше ничего. Повторяю: активация второго уровня является декларативной, вам не нужно модифицировать свой код.

Вторая ошибка: ваш текущий тест на самом деле не попадет в кеш второго уровня, второй цикл использует тот же сеанс и будет получать объекты из... сеанса (кэш первого уровня), а не из кеша второго уровня. Если вы хотите протестировать кеш второго уровня, используйте другой сеанс (т. е. закройте первый и получите другой из фабрики сеансов).

Я бы рекомендовал активировать ведение журнала для категории org.hibernate.cache, чтобы регистрировать всю активность кэша второго уровня и убедиться, что все работает должным образом.

Убедившись в этом, удалите ведение журнала и повторите свой (фиксированный) тест на большей выборке (x10 или x100).

person Pascal Thivent    schedule 17.05.2010

Hibernate будет автоматически использовать кеш второго уровня, когда вы добавите элемент <cache> в файл сопоставления. Вам не нужно явно управлять кешем до/после извлечения объектов из вашего сеанса.

Пробовали ли вы с большим количеством объектов? Тесты менее чем за секунду не очень надежны.

person mdma    schedule 17.05.2010