Nehmen wir an, ich habe zwei Entitäten, Employee
und Skill
. Jeder Mitarbeiter hat eine Reihe von Fähigkeiten. Jetzt, wenn ich die Fähigkeiten träge durch die Employee
Instanzen lade, wird der Cache nicht für Fähigkeiten in verschiedenen Instanzen von Employee
verwendet.Wie verwende ich Second Level Cache für Lazy Loaded Collections in Hibernate?
Betrachten wir den folgenden Datensatz.
Employee - 1 : Java, PHP
Employee - 2 : Java, PHP
Wenn ich Mitarbeiter laden - 2 nach Mitarbeiter - 1, ich will die Fähigkeiten nicht überwintern die Datenbank zu schlagen zu erhalten und stattdessen die Skill
Instanzen bereits im Cache verfügbar. Ist das möglich? Wenn das so ist, wie?
Hibernate Konfiguration
<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>
Die Entitäten mit Importen, Getter und Setter entfernt
@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 für das Laden der zweiten Mitarbeiter und seine Fähigkeiten
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=?
Dabei möchte ich insbesondere die zweite Abfrage vermeiden, da die erste sowieso unvermeidlich ist.
Ich habe das schon gemacht. Es vermeidet die Abfrage nur für diejenigen Mitarbeiter, die bereits geladen sind. Nicht Angestellte, die nicht im Cache sind und die gleichen Fähigkeiten wie ein anderer Mitarbeiter im Cache haben. In meinem ersten Beispiel würde es funktionieren, wenn ich Employee - 1 wieder lade, aber nicht wenn ich Employee - 2 lade. –
@Chandru Können Sie bitte Ihre Mappings ** und ** die generierte SQL zeigen? –
I'ev hat meine Frage aktualisiert, um die Informationen hinzuzufügen. –