2

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

2 回答 2

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)上重新运行(固定)测试。

于 2010-05-17T09:05:16.043 回答
0

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

您是否尝试过使用大量对象?低于一秒的基准并不是非常可靠。

于 2010-05-17T00:07:03.773 回答