2014-02-19 1 views
0

나 최대 절전 모드에서 두 번째 수준의 캐싱을 배우고 특정 세션입니다는 <p>이</p> 내 실체, 두 번째 레벨 캐시가 최대 절전 모드

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> 

는 IS 아래 코드는 내 질문이있는 곳입니다

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

쿼리 세 번 인쇄됩니다.

제 2 수준 캐시 구성이 맞습니까?

두 번째 레벨 캐시는 세션별로 있습니까?

코드에 어떤 변화가있어서 3 세션을 만들더라도 첫 번째 세션에서 'get'으로 얻은 첫 번째 고객을 다음 두 세션에서 공유해야합니다.

두 번째 레벨 캐시에있는 것과 동일한 고객에 대해 2 개의 선택 쿼리를 인쇄하지 않습니다.

답변

0

실제 쿼리는 트랜잭션을 커밋하거나 세션이 닫힐 때 실행됩니다. 세션을 개별적으로 닫지 않았으므로 각 get 메소드는로드 할 3 개의 다른 객체로 처리되므로 실행됩니다. 각 get 메소드 후에 세션을 닫으면 2 차 레벨 캐시가 검색되고 다음 get 메소드에 대해 검색됩니다. 따라서 get 메소드가 끝날 때마다 세션을 닫으십시오.