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!
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
Ja, das ist die Verwendung von Second-Level-Caching. Seien Sie vorsichtig damit: Ihre Entitäten werden nun zwischen Threads geteilt. – Thierry