3

二次キャッシュで Hibernate 4 を使い始めました。ドキュメントによると、構成は非常に簡単でした。

<property name="hibernate.cache.use_second_level_cache"  value="true"></property>
<property name="hibernate.cache.use_query_cache"  value="true"></property>
<property name="hibernate.cache.region.factory_class"  value="org.hibernate.cache.ehcache.EhCacheRegionFactory"></property>

私の理解によれば、第 2 レベルのキャッシュはデータベースへの同じクエリを排除するはずです。私は非常に単純なエンティティと非常に単純な名前付きクエリを持っています:

@Entity
@NamedQueries({
        @NamedQuery(name="SimplePerson.findByName", query="select p from SimplePerson p where p.name = :name"),
})

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SimplePerson {

    public static final String FIND_BY_NAME = "SimplePerson.findByName";

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;

    public SimplePerson() {

    }

    public SimplePerson(String name) {
        this.name = name;
    }



}

名前付きクエリを 4 回実行しましたが、残念ながら休止状態で 4 回実行されました。

EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");      
EntityManager em = emf.createEntityManager();

Query query = em.createNamedQuery(SimplePerson.FIND_BY_NAME);
query.setParameter("name", "BOB");

List result = query.getResultList();
result = query.getResultList();
result = query.getResultList();
result = query.getResultList();

出力:

Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?

2 番目のレベルのキャッシュについての私の理解では、何が問題なのですか? Hibernate がクエリを 4 回実行するのはなぜですか? いくつかの構成がありませんか?

前もってありがとう、マイケル

4

2 に答える 2

5

setCacheableメソッドはjavax.persistence.Queryからは利用できないため、名前付きクエリにキャッシュヒントを追加する(またはsetHintを呼び出す)必要があります。

@NamedQueries({
@NamedQuery(
    name="SimplePerson.findByName", 
    query="select p from SimplePerson p where p.name = :name", 
    hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") })
})

とは言うものの、クエリキャッシュを使用することでサメが飛び跳ねたので、それを検討する場合でも、次の記事を読む必要があります。最近では、SpringCachingの抽象化のようなより良いアプローチがあります。

于 2012-07-22T16:14:15.360 に答える
1

構成に次のものも含まれているべきではありません。

<cache usage="read-write"/>

cacheable="true"また、名前付きクエリにプロパティを 設定するかsetCacheable(true)、クエリ自体を実行する必要があることを忘れました。

PS:hibernateの構文はわかりませんが、NhibernateではそのSetCacheable(true)

于 2012-07-22T15:38:34.533 に答える