【问题标题】:No improvement in speed when using Ehcache with Hibernate将 Ehcache 与 Hibernate 一起使用时速度没有提高
【发布时间】:2011-02-20 05:13:39
【问题描述】:

将 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;
    }

【问题讨论】:

    标签: performance hibernate orm caching ehcache


    【解决方案1】:

    我看到的第一个错误是您正在处理 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)上重新运行(固定)测试。

    【讨论】:

      【解决方案2】:

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

      您是否尝试过处理更多的对象?不到一秒的基准测试并不是非常可靠。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-03
        • 2011-03-11
        • 2011-01-26
        • 1970-01-01
        • 2012-04-20
        • 2013-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多