Нет улучшения в скорости при использовании Ehcache с Hibernate - PullRequest
2 голосов
/ 17 мая 2010

У меня нет улучшения скорости при использовании 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>

stop.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;
    }

Ответы [ 2 ]

2 голосов
/ 17 мая 2010

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

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

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

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

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

Убедившись, удалите запись и повторите тест (фиксированный) на большем образце (х10 или х100).

0 голосов
/ 17 мая 2010

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

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

...