2016-06-08 6 views
1

Ich verwende Hibernate-Statistiken zum Sammeln von Informationen über 2 Ebenen Cache Miss oder Treffer. Warum, wenn ich Testmodul ausführen, habe ich nur Second Level Miss, aber nicht Hits? Warum der Second-Level-Cache in meinem Beispiel nicht funktioniert?Hibernate + Ehcache Second-Level-Cache-Miss in einfachen Beispiel

Ich habe nächsten 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> 

Und nächstes 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> 

Auch nächste 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> 

Und diese einfache Einheit:

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; 
    } 

} 

Mein Testmodul:

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!"); 

    } 
} 

Ausgang:

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

Antwort

2

Der Level 2 Cache zwischen verschiedenen Sitzungen zu Cache-Einheit verwendet. Da Sie sich in derselben Sitzung befinden, musste der Ruhezustand nicht in den Cache der Ebene 2 wechseln: Er konnte die Entität aus der Sitzung abrufen.

Und wie Sie sehen, bekommen Sie nur 52 Fehler, nicht 104. Nur die erste for-Schleife erzeugt diese Fehler. Dann holt Hibernate die Entitäten und fügt sie in die Sitzung und den Level 2-Cache ein. In der zweiten Schleife fand es sie in der Sitzung und musste nicht auf den Cache der Ebene 2 schauen, daher wurde weder ein Treffer noch ein Fehler erzeugt.

Um Level 2-Cache zu testen, schließen Sie die Transaktion und die Sitzung am Ende der ersten for-Schleife, und öffnen Sie neue (tx und Sitzung) vor der zweiten Schleife.

+0

Wirklich! Ich schließe die erste Sitzung und öffne eine andere und es funktioniert jetzt: Fetch Count = 52 Second Level Trefferanzahl = 52 Second Level Miss Anzahl = 52 Second Level Put Anzahl = 52 Complete! – Lev

+0

Ja, das ist die Verwendung von Second-Level-Caching. Seien Sie vorsichtig damit: Ihre Entitäten werden nun zwischen Threads geteilt. – Thierry