HIbernate查询缓存将结果缓存为null

时间:2014-07-18 19:21:29

标签: java hibernate caching ehcache

我正在使用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

我正在研究很长一段时间,但还没有结果。

1 个答案:

答案 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=?