繁体   English   中英

第二级缓存是Hibernate中特定于Session的吗

[英]Is second level cache is Session specific in Hibernate

我正在休眠中学习二级缓存,

这是我的实体

package com.hibernate.pojo;

import java.io.Serializable;
import javax.persistence.Entity;
 import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;


@Entity
@Table(name = "customer")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NamedQuery(query = "select c.customerName from Customer c",name = "findCustomerNames")
public class Customer implements Serializable{   

public Customer(){}
public Customer(Integer customerId){
    this.customerId = customerId;
}

public Customer(Integer customerId,String customerName){
    this.customerId = customerId;
    this.customerName = customerName;
}

@Id
private Integer customerId;
private String customerName;

/**
 * @return the customerId
 */
public Integer getCustomerId() {
    return customerId;
}

/**
 * @param customerId the customerId to set
 */
public void setCustomerId(Integer customerId) {
    this.customerId = customerId;
}

/**
 * @return the customerName
 */
public String getCustomerName() {
    return customerName;
}

/**
 * @param customerName the customerName to set
 */
public void setCustomerName(String customerName) {
    this.customerName = customerName;
}

@Override
public String toString(){
    StringBuffer strb = new StringBuffer();
    strb.append("\n\n CUSTOMER-ID : ")
            .append(this.customerId)
            .append("\n CUSTOMER-NAME : ")
            .append(this.customerName);
    return strb.toString();
}

@Override
public int hashCode(){
    return this.customerId * 29;
}

@Override
public boolean equals(Object object){
    boolean flag = false;

    if(object instanceof Customer){            
        Customer c = (Customer) object;
        flag =  (this.customerId == c.getCustomerId()) ? true : false;
    }
    return flag;
}   
}

这是我的休眠配置文件

<?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>

    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
    <property name="hibernate.connection.url">jdbc:derby://localhost:1527/sun-appserv-samples</property>
    <property name="hibernate.connection.username">app</property>
    <property name="hibernate.connection.password">app</property>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="show_sql">true</property>
    <property name="format_sql">true</property>                                                
            <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>                                
            <property name="hibernate.cache.use_query_cache">true</property>
            <property name="hibernate.cache.use_second_level_cache">true</property>
            <mapping class="com.hibernate.pojo.Customer" />
</session-factory>

</hibernate-configuration>

下面的代码是我的问题所在

    private static void getCustomer() throws Exception{
    Session session = HibernateUtil.getSessionFactory().openSession();
    Customer obj = null;
    obj =  (Customer)session.get(Customer.class, new Integer(2));
    session.close();
    session = HibernateUtil.getSessionFactory().openSession();
    obj = (Customer)session.get(Customer.class, new Integer(2));
    session.close();
    session = HibernateUtil.getSessionFactory().openSession();
    obj = (Customer)session.get(Customer.class, new Integer(2));        
    session.close();
    System.out.println(obj);
}

从上面的代码中您可以看到,我三次打开会话,三次关闭会话。 日志中打印的查询如下

Hibernate: 
select
    customer0_.customerId as customerId0_0_,
    customer0_.customerName as customer2_0_0_ 
from
    customer customer0_ 
where
    customer0_.customerId=?

在日志中,查询仅打印一次,

但是当我使用下面的代码

    private static void getCustomerFromSession() throws Exception{
    Session [] session = new Session[]{
        HibernateUtil.getSessionFactory().openSession(),
        HibernateUtil.getSessionFactory().openSession(),
        HibernateUtil.getSessionFactory().openSession()
    }; 

    Customer obj1 =  (Customer) session[0].get(Customer.class, new Integer(2));
    Customer obj2 = (Customer)  session[1].get(Customer.class, new Integer(2));
    Customer obj3 = (Customer)  session[2].get(Customer.class, new Integer(2));

    session[0].close();
    session[1].close();
    session[2].close();
}

我也希望在这里查询应该打印一次,但日志打印

Hibernate: 
select
    customer0_.customerId as customerId0_0_,
    customer0_.customerName as customer2_0_0_ 
from
    customer customer0_ 
where
    customer0_.customerId=?
Hibernate: 
select
    customer0_.customerId as customerId0_0_,
    customer0_.customerName as customer2_0_0_ 
from
    customer customer0_ 
where
    customer0_.customerId=?
Hibernate: 
select
    customer0_.customerId as customerId0_0_,
    customer0_.customerName as customer2_0_0_ 
from
    customer customer0_ 
where
    customer0_.customerId=?

但查询被打印三次。

那我的二级缓存配置正确吗?

二级缓存是特定于会话的吗?

我应该对代码进行哪些更改,以便即使我创建了3个会话,下一个两个会话也应共享从第一个会话的“获取”获得的第一个客户。

因此,对于与该客户在二级缓存中存在的客户相同的客户,不会进行2选择查询的打印。

当您提交事务或关闭会话时,将执行实际查询。 由于您没有分别关闭会话,因此将执行每个get方法,因为将其视为要加载的3个不同对象。 如果在每个get方法之后关闭该会话,则将查找二级缓存,并将为下一个get方法进行检索。 因此,尝试在每个get方法之后关闭会话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM