使用Ehcache和Hibernate时速度没有提高

时间:2010-05-16 23:47:50

标签: performance hibernate orm caching ehcache

使用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 个答案:

答案 0 :(得分:2)

我看到的第一个错误是你在Hibernate的二级缓存之上处理一个缓存,它将缓存Stop个实体。这只是无用的,二级缓存是透明的,你不需要在这里添加额外的类(如Element)或额外的代码。所以DAO方法应该是:

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

这就是全部,仅此而已。我再说一遍:激活第二级是声明性的,你不需要修改你的代码。

第二个错误:您当前的测试实际上不会达到二级缓存,第二个循环使用相同的Session并将从... Session(第一级缓存)获取对象,而不是来自二级缓存。如果要测试二级缓存,请使用另一个会话(即关闭第一个会话并从会话工厂中获取另一个会话)。

我建议激活类别org.hibernate.cache上的日志记录以记录所有二级缓存活动,并确保事情按预期工作。

确定后,删除记录并在较大的样本(x10或x100)上重新运行(固定)测试。

答案 1 :(得分:0)

当您将<cache>元素添加到映射文件时,Hibernate将自动使用二级缓存。在从Session中获取对象之前/之后,您无需显式管理缓存。

你尝试过大量的物品吗?一秒钟之内的基准测试并不十分可靠。