我正在使用ehcache进行hibernate二级cahe。使用查询缓存我的查询结果是没有正确缓存。 当第二次命中时,它只在对象的位置给出null。
这是我的所有配置。
CFG
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="xml-config">
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.default_schema">test</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cahe.user_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class"> org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.generate_statistics">true</property>
<!-- <mapping file="src/main/resources/Owner.hbm.xml" />
<mapping file="src/main/resources/RentalCar.hbm.xml" /> -->
<mapping class="com.annon.domain.RentalCar" />
<mapping class="com.annon.domain.Owner" />
</session-factory>
</hibernate-configuration>
POJO
package com.annon.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* @author ipg
*
*/
@Entity
@Table(name = "anon_owner")
@Cacheable(value = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="yourEntityCache")
public class Owner {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer ownerId;
private String name;
@ManyToMany(targetEntity = RentalCar.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "annon_car_owner", joinColumns = { @JoinColumn(nullable = false, name = "ownerId") }, inverseJoinColumns = { @JoinColumn(nullable = false, name = "carId") })
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="yourCollectionRegion")
private List<RentalCar> cars = new ArrayList<RentalCar>();
public Integer getOwnerId() {
return ownerId;
}
public void setOwnerId(Integer ownerId) {
this.ownerId = ownerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<RentalCar> getCars() {
return cars;
}
public void setCars(List<RentalCar> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "Owner [ownerId=" + ownerId + ", name=" + name + "]";
}
}
package com.annon.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Table(name = "annon_rental_car")
@Cacheable(value = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="yourEntityCache")
@NamedQueries(value = { @NamedQuery(name = "GetOwners", query = "select r.owners from RentalCar r where r.carId=?", hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }) })
@NamedNativeQueries(value = { @NamedNativeQuery(name = "GetOwnersByNative", query = "SELECT DISTINCT ownerId as ownerId,name as name FROM anon_owner ao JOIN annon_car_owner aco WHERE aco.cars_carId=?", hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }) })
public class RentalCar {
@Override
public String toString() {
return "RentalCar [carId=" + carId + ", carName=" + carName + "]";
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer carId;
private String carName;
@ManyToMany(mappedBy = "cars", fetch = FetchType.EAGER, cascade = CascadeType.ALL, targetEntity = Owner.class)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="yourCollectionRegion")
private List<Owner> owners = new ArrayList<Owner>();
public Integer getCarId() {
return carId;
}
public void setCarId(Integer carId) {
this.carId = carId;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public List<Owner> getOwners() {
return owners;
}
public void setOwners(List<Owner> owners) {
this.owners = owners;
}
}
我的测试代码
private static void testFetchWithNamedQuery() throws InterruptedException {
System.out.println("ManyToManyAnnonTest.testFetchWithNamedQuery()");
showCacheStatus();
Session session = factory.openSession();
Query query = session.getNamedQuery("GetOwners");
query.setParameter(0, 1);
System.out.println("List-" + query.list());
System.out.println("Cache Region-" + query.getCacheRegion());
System.out.println("contains-" + session.contains(query.list().get(0)));
session.close();
showCacheStatus();
Thread.sleep(300);
System.err.println("%%%%%%%%%%%%%%%%%% second phase start %%%%%%%%%%%%%%%%%%%%%%%");
session = factory.openSession();
query = session.getNamedQuery("GetOwners");
query.setParameter(0, 1);
System.out.println("List-" + query.list());
System.out.println("Cache Region-" + query.getCacheRegion());
showCacheStatus();
session.close();
}
private static void showCacheStatus() {
System.out.println("%%%%%%%%%%%%% DETAILS OF CACHE %%%%%%%%%%%%%%%");
org.hibernate.Cache cache = factory.getCache();
// net.sf.ehcache.CacheManager
// cacheManager=net.sf.ehcache.CacheManager.getInstance();
System.out.println("Query cache hit count-" + factory.getStatistics().getQueryCacheHitCount());
System.out.println("Query cache miss count-" + factory.getStatistics().getQueryCacheMissCount());
System.out.println("Query cache put count-" + factory.getStatistics().getQueryCachePutCount());
System.out.println("Query cache execution count-" + factory.getStatistics().getQueryExecutionCount());
System.out.println("factory.getStatistics().getCollectionLoadCount()--" + factory.getStatistics().getCollectionLoadCount());
System.out.println("factory.getStatistics().getCollectionFetchCount()--" + factory.getStatistics().getCollectionFetchCount());
System.out.println("Contains Owner 1-" + cache.containsEntity(Owner.class, 1));
System.out.println("Contains Car 1-" + cache.containsEntity(RentalCar.class, 1));
}
输出
%%%%%%%%%%%%% DETAILS OF CACHE %%%%%%%%%%%%%%%
Query cache hit count-0
Query cache miss count-0
Query cache put count-0
Query cache execution count-0
factory.getStatistics().getCollectionLoadCount()--0
factory.getStatistics().getCollectionFetchCount()--0
Contains Owner 1-false
Contains Car 1-false
Hibernate: select owner2_.ownerId as ownerId1_2_, owner2_.name as name2_2_ from test.annon_rental_car rentalcar0_ inner join test.annon_car_owner owners1_ on rentalcar0_.carId=owners1_.carId inner join test.anon_owner owner2_ on owners1_.ownerId=owner2_.ownerId where rentalcar0_.carId=?
Hibernate: select cars0_.ownerId as ownerId1_2_0_, cars0_.carId as carId2_0_0_, rentalcar1_.carId as carId1_1_1_, rentalcar1_.carName as carName2_1_1_ from test.annon_car_owner cars0_ inner join test.annon_rental_car rentalcar1_ on cars0_.carId=rentalcar1_.carId where cars0_.ownerId=?
Hibernate: select owners0_.carId as carId2_1_0_, owners0_.ownerId as ownerId1_0_0_, owner1_.ownerId as ownerId1_2_1_, owner1_.name as name2_2_1_ from test.annon_car_owner owners0_ inner join test.anon_owner owner1_ on owners0_.ownerId=owner1_.ownerId where owners0_.carId=?
Hibernate: select owners0_.carId as carId2_1_0_, owners0_.ownerId as ownerId1_0_0_, owner1_.ownerId as ownerId1_2_1_, owner1_.name as name2_2_1_ from test.annon_car_owner owners0_ inner join test.anon_owner owner1_ on owners0_.ownerId=owner1_.ownerId where owners0_.carId=?
**List-[Owner [ownerId=1, name=Owner]]**
Cache Region-null
contains-false
%%%%%%%%%%%%% DETAILS OF CACHE %%%%%%%%%%%%%%%
Query cache hit count-1
Query cache miss count-1
Query cache put count-1
Query cache execution count-1
factory.getStatistics().getCollectionLoadCount()--3
factory.getStatistics().getCollectionFetchCount()--3
Contains Owner 1-true
Contains Car 1-true
%%%%%%%%%%%%%%%%%% second phase start %%%%%%%%%%%%%%%%%%%%%%%
**List-[null]**
Cache Region-null
%%%%%%%%%%%%% DETAILS OF CACHE %%%%%%%%%%%%%%%
Query cache hit count-2
Query cache miss count-1
Query cache put count-1
Query cache execution count-1
factory.getStatistics().getCollectionLoadCount()--3
factory.getStatistics().getCollectionFetchCount()--3
Contains Owner 1-true
Contains Car 1-true
我正在研究很长一段时间,但还没有结果。
答案 0 :(得分:0)
我通过更改HQL来修复它
旧HQL
select r.owners from RentalCar r where r.carId=?
修正了HQL
select o from RentalCar c join c.owners o where c.carId=?