2

Hibernate で Ehcache を使用しても速度が向上しません

以下のテストを実行したときに得られる結果は次のとおりです。テストでは、80 個の Stop オブジェクトを読み取り、次にキャッシュを使用して同じ 80 個の Stop オブジェクトを再度読み取ります。

2 回目の読み取りではキャッシュにヒットしていますが、速度の向上はありません。私が間違っていることについて何か考えはありますか?

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

2 に答える 2

2

Stop私が目にする最初の間違いは、すでにエンティティをキャッシュしている Hibernate の第 2 レベルのキャッシュの上にあるキャッシュを処理していることです。Elementそれは役に立たないだけです。第 2 レベルのキャッシュは透過的です。追加のクラス (ここのように) や追加のコードを追加する必要はありません。したがって、DAO メソッドは次のようになります。

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

それだけです。繰り返しますが、第 2 レベルのアクティブ化は宣言型であり、コードを変更する必要はありません。

2 番目の間違い: 現在のテストは実際には 2 番目のレベルのキャッシュにヒットしません。2 番目のループは同じセッションを使用し、2 番目のレベルのキャッシュではなく、セッション (1 番目のレベルのキャッシュ) からオブジェクトを取得します。2 番目のレベルのキャッシュをテストする場合は、別のセッションを使用します (つまり、最初のセッションを閉じて、セッション ファクトリから別のセッションを取得します)。

カテゴリのログを有効にして、org.hibernate.cacheすべての二次キャッシュ アクティビティをログに記録し、期待どおりに機能していることを確認することをお勧めします。

確認したら、ロギングを削除し、より大きなサンプル (x10 または x100) で (固定) テストを再実行します。

于 2010-05-17T09:05:16.043 に答える
0

<cache>要素をマッピング ファイルに追加すると、Hibernate は自動的に第 2 レベルのキャッシュを使用します。セッションからオブジェクトをフェッチする前後にキャッシュを明示的に管理する必要はありません。

より多くのオブジェクトで試しましたか? 1 秒未満のベンチマークはあまり信頼できません。

于 2010-05-17T00:07:03.773 に答える