Hibernate甚至会在缓存命中时抛出查询

时间:2014-02-23 14:02:30

标签: java spring hibernate jpa ehcache

我不确定这是否是一个真正的问题,或者只是配置问题,但我可以在我的日志控制台上看到hibernate如何命中(或者至少抛出select查询)甚至在缓存命中。

我已经检查过缓存是否在Ehcache监视器上正常工作,并且它为特定请求注册了100%的命中。但我总是在日志中看到查询。

所有实体都按照所示进行分配:

@Entity
@Cacheable
@Cache(usage = READ_WRITE)
@Table(name = "city")
//@NamedQuery(name = "city.findById", query = "from City where ID = :id")
public class City extends Audit implements Serializable {

我的ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
    dynamicConfig="true" monitoring="autodetect">

    <!-- Location of persistent caches on disk -->
    <diskStore path="java.io.tmpdir/MxlServiceLayer" />

    <cacheManagerPeerListenerFactory
        class="org.terracotta.ehcachedx.monitor.probe.ProbePeerListenerFactory"
        properties="monitorAddress=localhost, monitorPort=9889, memoryMeasurement=true" />
    <defaultCache eternal="false" maxElementsInMemory="1000"
        overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
        timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" statistics="true" />
    <cache name="authToken" eternal="false" maxElementsInMemory="100"
        overflowToDisk="false" diskPersistent="true" timeToIdleSeconds="0"
        timeToLiveSeconds="31536000" memoryStoreEvictionPolicy="LRU"
        statistics="true" />
</ehcache>

我一遍又一遍地看到了......

  

Hibernate:选择city0_.ID为ID2_,city0_.CREATED为CREATED2_,   city0_.CREATOR as CREATOR2_,city0_.MODIFIED as MODIFIED2_,   city0_.MODIFIER为MODIFIER2_,city0_.NAME为NAME2_,city0_.state_fk   as state7_2_ from city city0_ where State_fk =?

hibernate真的击中了数据库吗?有人可以向我解释一下吗?

我正在使用:

  

Spring Data JPA 1.2.0中的JPA 2.0

     

Ehcache 2.6.0

     

Spring 3.2.1

1 个答案:

答案 0 :(得分:4)

您启用的是二级缓存。此缓存缓存实体的状态,并按ID对其进行索引。这就像Map<ID, EntityState>。仅当您通过ID获取实体时才使用此缓存:

  • 通过调用session.get()
  • 通过调用session.load()
  • 浏览目标实体的XxxToOne关联

您的查询不属于此类别:它会通过其中一个字段查找您的实体,而不是通过其ID查找。

对于其余部分,Hibernate无法对缓存执行任意SQL查询,即使可以,缓存也只包含表的子集,因此它必须查询数据库。

但是,您也可以缓存查询结果。您需要启用查询缓存才能执行此操作,并启用mark your query as cacheable。您还可以缓存关联(这似乎是此查询的原因:它正在查找给定状态的所有城市)。您必须使用@Cache注释关联。

阅读the documentation