Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to use second level cache for lazy loaded collections in Hibernate?
    text
    copied!<p>Let's say I have two entities, <code>Employee</code> and <code>Skill</code>. Every employee has a set of skills. Now when I load the skills lazily through the <code>Employee</code> instances the cache is not used for skills in different instances of <code>Employee</code>.</p> <p>Let's Consider the following data set.</p> <pre><code>Employee - 1 : Java, PHP Employee - 2 : Java, PHP </code></pre> <p>When I load Employee - 2 after Employee - 1, I do not want hibernate to hit the database to get the skills and instead use the <code>Skill</code> instances already available in cache. Is this possible? If so how?</p> <p><strong>Hibernate Configuration</strong></p> <pre><code>&lt;session-factory&gt; &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt; &lt;property name="hibernate.connection.password"&gt;pass&lt;/property&gt; &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost/cache&lt;/property&gt; &lt;property name="hibernate.connection.username"&gt;root&lt;/property&gt; &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/property&gt; &lt;property name="hibernate.cache.use_second_level_cache"&gt;true&lt;/property&gt; &lt;property name="hibernate.cache.use_query_cache"&gt;true&lt;/property&gt; &lt;property name="hibernate.cache.provider_class"&gt;net.sf.ehcache.hibernate.EhCacheProvider&lt;/property&gt; &lt;property name="hibernate.hbm2ddl.auto"&gt;update&lt;/property&gt; &lt;property name="hibernate.show_sql"&gt;true&lt;/property&gt; &lt;mapping class="org.cache.models.Employee" /&gt; &lt;mapping class="org.cache.models.Skill" /&gt; &lt;/session-factory&gt; </code></pre> <p><strong>The Entities with imports, getters and setters Removed</strong></p> <pre><code>@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&lt;Skill&gt; skills; } @Entity @Table(name = "skill") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Skill { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; } </code></pre> <p><strong>SQL for Loading the Second Employee and his Skills</strong></p> <pre><code>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=? </code></pre> <p>In that I specifically want to avoid the second query as the first one is unavoidable anyway.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload