2016-06-08 1 views
1

J'utilise les statistiques hibernate pour collecter des informations sur 2 cache manquant ou hits. Pourquoi quand j'exécute le module de test, je n'ai que le second niveau Miss mais pas Hits? Pourquoi le cache de deuxième niveau ne fonctionne pas dans mon exemple?Hibernate + cache cache ehcache de second niveau dans un exemple simple

J'ai à côté 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> 

Et à côté 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> 

Aussi, à côté 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> 

Et ce simple entité:

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

} 

Mon module d'essai:

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

    } 
} 

sortie:

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

Répondre

2

Le cache de niveau 2 est utilisé à l'entité de cache entre les différentes sessions. Ici vous êtes dans la même session, donc Hibernate n'a pas eu à aller au cache de niveau 2: il pourrait obtenir l'entité de la session. Et comme vous le voyez, vous n'obtenez que 52 échecs, pas 104. Seule la première boucle génère ces échecs. Alors hibernate obtient les entités, les mettant dans la session et le cache de niveau 2. Sur la deuxième boucle, il les a trouvés dans la session et n'a pas eu à regarder le cache de niveau 2, donc aucun hit ni miss généré.

Pour tester le cache de niveau 2, fermez la transaction et la session à la fin de la première boucle for et ouvrez-en de nouvelles (tx et session) avant la deuxième boucle.

+0

Vraiment! Je ferme la première session et en ouvre une autre et cela fonctionne maintenant: Fetch Count = 52 Deuxième niveau Nombre de hits = 52 Deuxième niveau Miss Count = 52 Deuxième niveau Put Put = 52 Terminé! – Lev

+0

Oui c'est l'utilisation de la mise en cache de second niveau. Soyez prudent avec cela: maintenant vos entités sont partagées entre les threads. – Thierry