【问题标题】:Hibernate throws queries even on cache hits即使在缓存命中时,Hibernate 也会引发查询
【发布时间】:2014-02-23 14:02:29
【问题描述】:

我不确定这是一个真正的问题还是只是配置问题,但我可以在我的日志控制台上看到即使在缓存命中时休眠如何命中(或至少抛出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>

而我一遍又一遍地看到的……

休眠:选择 city0_.ID 作为 ID2_,city0_.CREATED 作为 CREATED2_, city0_.CREATOR 作为 CREATOR2_,city0_.MODIFIED 作为 MODIFIED2_, city0_.MODIFIER 作为 MODIFIER2_,city0_.NAME 作为 NAME2_,city0_.state_fk 作为 state7_2_ 从城市 city0_ where State_fk=?

hibernate 真的会影响数据库吗?谁能给我解释一下,好吗?

我正在使用:

Spring Data JPA 1.2.0 中的 JPA 2.0

Ehcache 2.6.0

春季 3.2.1

【问题讨论】:

    标签: java spring hibernate jpa ehcache


    【解决方案1】:

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

    • 通过调用 session.get()
    • 通过调用 session.load()
    • 通过以实体为目标的 XxxToOne 关联导航

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

    另外,Hibernate 不能对缓存执行任意 SQL 查询,即使可以,缓存也只包含表的子集,因此它必须查询数据库。

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

    阅读the documentation

    【讨论】:

    • 你的方法似乎是正确的,但由于我使用的是 Spring Data 的 JPA,它目前不支持查询缓存。
    • @AminAbu-Taleb 即使在 spring data jpa 中,您也可以使用 QueryHint 告诉使用休眠查询缓存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2018-12-20
    相关资源
    最近更新 更多