Digamos que tengo dos entidades, Employee
y Skill
. Cada empleado tiene un conjunto de habilidades. Ahora cuando cargo las habilidades perezosamente a través de las instancias Employee
, la caché no se usa para habilidades en diferentes instancias de Employee
.¿Cómo usar la memoria caché de segundo nivel para colecciones cargadas perezosas en Hibernate?
Consideremos el siguiente conjunto de datos.
Employee - 1 : Java, PHP
Employee - 2 : Java, PHP
Cuando cargo del empleado - 2 después de Empleado - 1, no quiero hibernar para golpear la base de datos para obtener las habilidades y en su lugar utilizar los Skill
casos ya está disponible en la memoria caché. es posible? ¿Si es así, cómo?
configuración de hibernación
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pass</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/cache</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<mapping class="org.cache.models.Employee" />
<mapping class="org.cache.models.Skill" />
</session-factory>
las entidades con las importaciones, captadores y definidores Eliminado
@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
public Employee() {
}
@ManyToMany
@JoinTable(name = "employee_skills", joinColumns = @JoinColumn(name = "employee_id"), inverseJoinColumns = @JoinColumn(name = "skill_id"))
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<Skill> skills;
}
@Entity
@Table(name = "skill")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Skill {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
SQL para cargar el segundo de los empleados y sus habilidades
Hibernate: select employee0_.id as id0_0_, employee0_.name as name0_0_ from employee employee0_ where employee0_.id=?
Hibernate: select skills0_.employee_id as employee1_1_, skills0_.skill_id as skill2_1_, skill1_.id as id1_0_, skill1_.name as name1_0_ from employee_skills skills0_ left outer join skill skill1_ on skills0_.skill_id=skill1_.id where skills0_.employee_id=?
Quiero evitar específicamente la segunda consulta, ya que la primera es inevitable de todos modos.
Ya he hecho esto. Evita la consulta solo para aquellos empleados que ya están cargados. No empleados que no están en caché y que también tienen las mismas habilidades que otro empleado que ya está en el caché. En mi ejemplo inicial, funcionaría si cargo Empleado - 1 nuevamente pero no cuando cargo Empleado - 2. –
@Chandru ¿Puede mostrar sus asignaciones ** y ** el SQL generado? –
He actualizado mi pregunta para agregar la información. –