Hibernate EhCache没用过?

Hibernate EhCache not used?

这是我的一部分 persistence.xml

<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE" />

<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.show_sql" value="true" />            
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.generate_statistics" value="true"/>

<!-- set cache provider -->
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />

<!-- enable second level cache and query cache -->
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />

ehcache.xml

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

    <diskStore path="java.io.tmpdir/ehcache" />

    <defaultCache 
        maxEntriesLocalHeap="10000" 
        eternal="false"
        timeToIdleSeconds="120" 
        timeToLiveSeconds="120" 
        diskSpoolBufferSizeMB="30"
        maxEntriesLocalDisk="10000000" 
        diskExpiryThreadIntervalSeconds="120"
        statistics="true">
        <persistence strategy="localTempSwap" />
    </defaultCache>

</ehcache>

最后,main 方法(我想兼容 JPA)

void main()
{
    EntityManagerFactory emf = null;        
    EntityManager em = null; 

    try {

        emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

        em = emf.createEntityManager();

        Session session = em.unwrap( Session.class );

        Customer find;

        Transaction transaction = session.getTransaction();

        transaction.begin();

        CustomerPk pk = new CustomerPk();
        pk.setUidCliente("fabrizio.sttrd0l7c0@gmail.com");

        find = em.find(Customer.class, pk);

        find = em.find(Customer.class, pk);

        transaction.commit();

        logger.info("END");

    } catch (Exception e) {
        logger.error(e.getMessage());
    } finally {
        Optional.ofNullable(em).ifPresent(x -> { x.close(); });
        Optional.ofNullable(emf).ifPresent(x -> { x.close(); });            
    }
}

现在我希望二级缓存在第二次 find 调用时应该是 'hitted',但事实并非如此,因为记录的统计信息打印如下:

20786 nanoseconds spent acquiring 1 JDBC connections;
20057 nanoseconds spent releasing 1 JDBC connections;
169837247 nanoseconds spent preparing 1 JDBC statements;
322972879 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
4190446 nanoseconds spent performing 1 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
1239520 nanoseconds spent performing 1 L2C misses;
6351857 nanoseconds spent executing 1 flushes (flushing a total of 1 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)

如您所见,0 次 L2C 命中。

这有什么问题?

您对两个提取操作使用相同的 EntityManager,因此它不需要到达 l2 缓存,因为 l1 已经匹配。

L1 缓存是实体管理器状态,因此绑定到 EM 生命周期。 L2 缓存在 entityManagerFactory 级别,并在同一工厂创建的所有 EM 之间共享。