[英]Hibernate 4 with second level cache: what wrong in my understanding?
我已经开始使用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>
根据我的理解,二级缓存应该消除对数据库的相同查询。 我有非常简单的实体和非常简单的命名查询:
@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次,不幸的是我看到hibernate运行了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=?
我对二级缓存的理解有什么问题? 为什么Hibernate运行查询4次? 我是否会错过一些配置?
迈克尔,提前谢谢
javax.persistence.Query中没有setCacheable方法,因此您需要将缓存提示添加到命名查询(或调用setHint):
@NamedQueries({
@NamedQuery(
name="SimplePerson.findByName",
query="select p from SimplePerson p where p.name = :name",
hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") })
})
也就是说,使用查询缓存已经跳过了鲨鱼,如果你甚至要考虑它, 下面的文章是必读的 。 现在有更好的方法,如Spring Caching抽象。
你不应该在你的配置中有以下内容:
<cache usage="read-write"/>
另外我忘了你需要在运行查询本身时在命名查询或setCacheable(true)
上设置cacheable="true"
属性。
PS:不确定hibernate中的语法是什么,但在Nhibernate中它的SetCacheable(true)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.