2010-02-18 25 views
8

Giả sử tôi có hai thực thể, EmployeeSkill. Mỗi nhân viên đều có một bộ kỹ năng. Bây giờ khi tôi tải các kỹ năng một cách uể oải qua các trường hợp Employee, bộ nhớ cache không được sử dụng cho các kỹ năng trong các trường hợp khác nhau của Employee.Làm thế nào để sử dụng bộ nhớ cache cấp thứ hai cho bộ sưu tập tải lười biếng trong Hibernate?

Hãy xem xét tập dữ liệu sau.

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

Khi tôi nạp nhân viên - 2 sau khi nhân viên - 1, tôi không muốn ngủ đông để đạt cơ sở dữ liệu để có được những kỹ năng và thay vào đó sử dụng Skill trường hợp đã có sẵn trong bộ nhớ cache. Điều này có thể không? Nếu thế thì sao?

Hibernate Cấu hình

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

Các thực thể với hàng nhập khẩu, getter và setter Removed

@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 cho tải Employee thứ hai và kỹ năng của mình

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

Trong đó tôi đặc biệt muốn tránh truy vấn thứ hai là truy vấn thứ nhất là không thể tránh khỏi.

Trả lời

4

Bạn cần lưu trữ liên kết Employee--<>Skills. Ví dụ lấy từ Speed Up Your Hibernate Applications with Second-Level Caching dưới đây:

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

Lưu ý các yếu tố <cache> bên trong của ngôn ngữ.

+0

Tôi đã thực hiện việc này rồi. Nó tránh truy vấn chỉ cho những nhân viên đã được tải. Không phải nhân viên không có trong bộ nhớ cache cũng có các kỹ năng giống như một nhân viên khác đã có trong bộ nhớ cache. Trong ví dụ ban đầu, nó sẽ hoạt động nếu tôi tải Nhân viên - 1 lần nữa nhưng không phải khi tôi tải Nhân viên - 2. –

+0

@Chandru Bạn có thể hiển thị ánh xạ của bạn ** và ** SQL được tạo không? –

+0

I'ev đã cập nhật câu hỏi của tôi để thêm thông tin. –

Các vấn đề liên quan