2010-02-18 12 views
8

Powiedzmy mam dwa podmioty, Employee i Skill. Każdy pracownik ma zestaw umiejętności. Teraz, gdy ładuję umiejętności leniwie przez instancje Employee, pamięć podręczna nie jest używana dla umiejętności w różnych instancjach Employee.Jak używać pamięci podręcznej drugiego poziomu dla leniwych wczytanych kolekcji w trybie hibernacji?

rozważmy następujący zestaw danych.

Employee - 1 : Java, PHP 
Employee - 2 : Java, PHP 

Kiedy załadować Pracownik - 2 po Pracownik - 1, nie chcę hibernacji trafić do bazy danych w celu zdobycia umiejętności i zamiast korzystania z Skill instancji już dostępne w pamięci podręcznej. czy to możliwe? Jeśli tak to jak?

Hibernate konfiguracji

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

Podmioty z importem, pobierające i ustawiające Usunięto

@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 dla Wkładanie Drugi pracownik i jego umiejętności

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

W szczególności, że chcą uniknąć drugą kwerendę jako pierwszy i tak jest nieuniknione.

Odpowiedz

4

trzeba buforować stowarzyszenie Employee--<>Skills. Przykładem z Speed Up Your Hibernate Applications with Second-Level Caching poniżej

<hibernate-mapping package="com.wakaleo.articles.caching.businessobjects"> 
    <class name="Employee" table="EMPLOYEE" dynamic-update="true"> 
     <meta attribute="implement-equals">true</meta>  

     <id name="id" type="long" unsaved-value="null" > 
      <column name="emp_id" not-null="true"/> 
      <generator class="increment"/> 
     </id> 

    <property column="emp_surname" name="surname" type="string"/> 
    <property column="emp_firstname" name="firstname" type="string"/> 

    <many-to-one name="country" 
      column="cn_id" 
       class="com.wakaleo.articles.caching.businessobjects.Country" 
      not-null="true" /> 

    <!-- Lazy-loading is deactivated to demonstrate caching behavior -->  
    <set name="languages" table="EMPLOYEE_SPEAKS_LANGUAGE" lazy="false"> 
     <cache usage="read-write"/> 
     <key column="emp_id"/> 
      <many-to-many column="lan_id" class="Language"/> 
    </set>        
    </class> 
</hibernate-mapping> 

Uwaga element <cache> wewnątrz języków.

+0

Robiłem to już. Pozwala uniknąć zapytania tylko dla tych pracowników, którzy są już załadowani. Nie pracownicy, którzy nie są zapisani w pamięci podręcznej i mają te same umiejętności, co inny pracownik, który już znajduje się w pamięci podręcznej. W moim początkowym przykład będzie działać, jeśli załadować Pracownik - 1 raz, ale nie kiedy załadować pracownika - 2. –

+0

@Chandru Czy możesz pokazać swoje mapowania ** i ** wygenerowany SQL? –

+0

I'ev zaktualizowałem moje pytanie, aby dodać informacje. –

Powiązane problemy