2010-02-18 9 views
8

मान लें कि मेरे पास दो इकाइयां हैं, Employee और Skill। प्रत्येक कर्मचारी के पास कौशल का एक सेट होता है। अब जब मैं Employee के माध्यम से आलसी कौशल को लोड करता हूं तो Employee के विभिन्न उदाहरणों में कौशल के लिए कैश का उपयोग नहीं किया जाता है।हाइबरनेट में आलसी लोड किए गए संग्रह के लिए दूसरे स्तर के कैश का उपयोग कैसे करें?

चलिए निम्नलिखित डेटा सेट पर विचार करें।

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

जब मैं कर्मचारी लोड - कर्मचारी के बाद 2 - 1, मैं नहीं चाहता कि कौशल प्राप्त और बदले कैश में Skill उदाहरणों पहले से ही उपलब्ध उपयोग करने के लिए डेटाबेस हिट करने के लिए हाइबरनेट चाहते हैं। क्या यह संभव है? यदि हां, तो कैसे?

हाइबरनेट विन्यास

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

आयात, टिककर खेल के साथ संस्थाओं और setters लोड हो रहा है दूसरा कर्मचारी और उनके कौशल के कारण हटा दिया

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

एसक्यूएल

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

उस में मैं विशेष रूप से दूसरी क्वेरी से बचना चाहता हूं क्योंकि वैसे भी पहला व्यक्ति अपरिहार्य है।

उत्तर

4

आपको Employee--<>Skills एसोसिएशन को कैश करने की आवश्यकता है।

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

नोट भाषाओं के अंदर <cache> तत्व: उदाहरण Speed Up Your Hibernate Applications with Second-Level Caching से नीचे ले लिया।

+0

मैंने इसे पहले से ही किया है। यह केवल उन कर्मचारियों के लिए क्वेरी से बचाता है जो पहले ही लोड हो चुके हैं। कर्मचारी कैश में नहीं हैं जिनके पास पहले से ही कैश में दूसरे कर्मचारी के समान कौशल भी हैं। मेरे प्रारंभिक उदाहरण में यह काम करेगा यदि मैं कर्मचारी -1 को फिर से लोड करता हूं लेकिन जब मैं कर्मचारी लोड नहीं करता - 2. –

+0

@Chandru क्या आप कृपया अपने मैपिंग ** और ** जेनरेट किए गए एसक्यूएल दिखा सकते हैं? –

+0

मैंने जानकारी जोड़ने के लिए अपना प्रश्न अपडेट किया है। –

संबंधित मुद्दे