2016-06-08 94 views
1

我使用休眠統計來收集有關2級高速緩存缺失或命中的信息。 爲什麼當我執行測試模塊時,我只有二級小姐但沒有點擊? 爲什麼二級緩存在我的例子中不起作用?簡單示例中的休眠+ ehcache二級高速緩存缺失

我旁邊的hibernate.cfg.xml:

<?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 
    <hibernate-configuration> 
    <session-factory> 
     <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
     <property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.100.0:1521:rrr</property> 
     <property name="hibernate.connection.username">ora</property> 
     <property name="hibernate.connection.password">lll</property> 
     <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> 
     <property name="hibernate.default_schema">ora</property> 
     <property name="hibernate.current_session_context_class">thread</property> 
     <property name="hibernate.generate_statistics">true</property> 
     <property name="show_sql">false</property> 
     <property name="format_sql">false</property> 
     <property name="use_sql_comments">false</property> 

     <property name="hibernate.cache.use_second_level_cache">true</property> 
     <property name="hibernate.cache.use_query_cache">true</property> 
     <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> 
     <property name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property> 


     <mapping class="com.ric.bill.model.bs.Lst"></mapping> 
     <mapping class="com.ric.bill.model.bs.LstTp"></mapping> 

    </session-factory> 
</hibernate-configuration> 

而接下來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="true"> 

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

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

    <cache name="billCache" maxEntriesLocalHeap="10000" 
     eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0"> 
     <persistence strategy="localTempSwap" /> 
    </cache> 

    <cache name="org.hibernate.cache.internal.StandardQueryCache" 
     maxEntriesLocalHeap="5000" eternal="false" timeToLiveSeconds="120"> 
     <persistence strategy="localTempSwap" /> 
    </cache> 

    <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" 
     maxEntriesLocalHeap="5000" eternal="true"> 
     <persistence strategy="localTempSwap" /> 
    </cache> 
</ehcache> 

而且,未來的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<groupId>com.journaldev.hibernate</groupId> 
<artifactId>HibernateEHCacheExample</artifactId> 
<version>0.0.1-SNAPSHOT</version> 
<description>Hibernate Secondary Level Cache Example using EHCache implementation</description> 

<dependencies> 
    <!-- Hibernate Core API --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>5.1.0.Final</version> 
    </dependency> 
    <!-- EHCache Core APIs --> 
    <!-- http://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core --> 
    <dependency> 
     <groupId>net.sf.ehcache</groupId> 
     <artifactId>ehcache-core</artifactId> 
     <version>2.6.11</version> 
    </dependency> 

    <!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-ehcache</artifactId> 
     <version>5.2.0.Final</version> 
    </dependency> 

    <!-- EHCache uses slf4j for logging --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-simple</artifactId> 
     <version>1.7.5</version> 
    </dependency> 
</dependencies> 
</project> 

而這個簡單的實體:

package com.ric.bill.model.bs; 

import javax.persistence.Cacheable; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

import org.hibernate.annotations.Cache; 
import org.hibernate.annotations.CacheConcurrencyStrategy; 

import com.ric.bill.Simple; 

@SuppressWarnings("serial") 
@Entity 
@Table(name = "LIST", schema="BS") 
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="billCache") 
@Cacheable 
public class Lst implements java.io.Serializable, Simple { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID", updatable = false, nullable = false) 
    private Integer id; //id 

    @Column(name = "CD", updatable = false, nullable = false) 
    private String cd; //cd 

    @Column(name = "NAME", updatable = false, nullable = false) 
    private String name; //Наименование 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="FK_LISTTP", referencedColumnName="ID") 
    private LstTp lstTp ; 


    public Integer getId() { 
     return this.id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getCd() { 
     return this.cd; 
    } 
    public void setCd(String cd) { 
     this.cd = cd; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public LstTp getLstTp() { 
     return lstTp; 
    } 
    public void setLstTp(LstTp lstTp) { 
     this.lstTp = lstTp; 
    } 

} 

我的測試模塊:

public class Test { 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     SessionFactory sf = HibernateUtil.getSessionFactory(); 
     Session sess = sf.openSession(); 
     sess.beginTransaction(); 

     for (int a=1401; a<=1452; a++) { 
      Lst lst = (Lst) sess.load(Lst.class, a); 
      System.out.println(lst.getName()); 
     } 
     for (int a=1401; a<=1452; a++) { 
      Lst lst = (Lst) sess.load(Lst.class, a); 
      System.out.println(lst.getName()); 
     } 
     Statistics stats = sf.getStatistics(); 
     printStats(stats, 0); 

     sess.getTransaction().commit(); 

     System.out.println("Complete!"); 

    } 
} 

輸出:

Fetch Count=52 
Second Level Hit Count=0 
Second Level Miss Count=52 
Second Level Put Count=52 
Complete! 

回答

2

的2級高速緩存被用於不同的會話之間的高速緩存的實體。這裏你在同一個會話中,所以hibernate不必去二級緩存:它可以從會話中獲得實體。

正如你所看到的,你只能得到52次失誤,而不是104次。只有第一次for循環會產生這些失誤。然後休眠獲取實體,將它們放入會話和二級緩存中。在第二個循環中,它在會話中找到了它們,並且不必查看二級緩存,因此不會生成命中或未命中。

要測試2級緩存,請在第一個for循環結束時關閉事務和會話,並在第二個循環之前打開新的(tx和session)。

+0

真的!我關閉第一次會議,並打開另一個,它現在工作:取得計數= 52 二級命中計數= 52 二級小姐計數= 52 二級放置計數= 52 完成! – Lev

+0

是的,這是使用二級緩存。要小心:現在你的實體在線程之間共享。 – Thierry