Pregunta

I am learning second level caching in hibernate,

this is my entity

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;
}   
}

This is my hibernate config file

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

The code below is where my question lies

    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);
}

From the code above you can see, i am opening the session thrice and close it thrice. the query printed in the log is as follows

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

in the logs the query is printed only once,

but when i use the below code

    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();
}

i expect here too that the query should be printed once, but the logs print

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

but the query is printed thrice.

So is my second level cache configuration correct ?

Is second level cache a session specific ?

What changes i should do to my code so that even if i create 3 session, the first Customer obtained from 'get' from first session should be shared by the next two session.

so no printing for 2 select query for the same customer as its present in second level cache.

¿Fue útil?

Solución

Actual queries are executed when you commit the transaction or when session is closed. As you did not close the sessions individually, each get method is executed as it is treated 3 different objects to be loaded. If close the session after each get method, then 2nd level cache is looked up and it will be retrieved for next get method. So try closing the session after each get method.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top