Second-­‐Level	
  Cache	
  	
  
in	
  JPA	
  Explained
Patrycja	
  Wegrzynowicz	
  
CTO,	
  Yonita,	
  Inc.	
  
JavaOne	
 ...
About	
  Me
• 15+	
  professional	
  experience	
  	
  
• SoPware	
  engineer,	
  architect,	
  head	
  of	
  
soPware	
  ...
About	
  Me
• 15+	
  professional	
  experience	
  	
  
• SoPware	
  engineer,	
  architect,	
  head	
  of	
  
soPware	
  ...
Agenda
• Why	
  cacheing	
  is	
  important?	
  
• 1st	
  Level	
  Cache	
  and	
  2nd	
  Level	
  Cache	
  
• JPA	
  confi...
Databases
Databases
Performance
Request	
  Handling
Performance:	
  Throughput
Performance:	
  ExecuXon	
  Time
Performance:	
  Latency
Performance:	
  Response	
  Time
Example
Employee	
  Entity
@Entity public class Employee {

@Id @GeneratedValue
private Long id;

private String firstName; 

priv...
Sum	
  of	
  Salaries	
  By	
  Country

Select	
  All	
  (1)
TypedQuery<Employee> query = em.createQuery(
"SELECT e FROM E...
Sum	
  of	
  Salaries	
  by	
  Country

Select	
  Join	
  Fetch	
  (2)
TypedQuery<Employee> query = em.createQuery(
"SELEC...
Sum	
  of	
  Salaries	
  by	
  Country

Projection	
  (3)
Query query = em.createQuery(
"SELECT e.salary, e.address.countr...
Sum	
  of	
  Salaries	
  by	
  Country

Aggregation	
  JPQL	
  (4)
Query query = em.createQuery(
"SELECT SUM(e.salary), e....
Comparison	
  1-­‐4	
  (Hibernate)	
  
100000	
  Employees,	
  Different	
  DB	
  LocaXons
Local DB
(ping: ~0.05ms)
North C...
Comparison	
  1-­‐4	
  
100000	
  Employees,	
  Different	
  DB	
  LocaXons
Local DB
(ping: ~0.05ms)
North California
(ping...
Comparison	
  1-­‐4	
  
100000	
  Employees,	
  Different	
  DB	
  LocaXons
Local DB
(ping: ~0.05ms)
North California
(ping...
Comparison	
  1-­‐4	
  
100000	
  Employees,	
  Different	
  DB	
  LocaXons
Local DB
(ping: ~0.05ms)
North California
(ping...
Performance	
  Tuning:	
  Data
• Get	
  your	
  data	
  in	
  bigger	
  chunks	
  	
  
• Many	
  small	
  queries	
  =>	
 ...
Cache	
  is	
  Everywhere
Web Cache
Application Cache
RDBMS Cache
DNS Cache
OS Files Cache
Second	
  Level	
  Cache	
  in	
  
JPA
JPA	
  Spec
• “Persistence	
  providers	
  are	
  not	
  required	
  to	
  support	
  a	
  
second-­‐level	
  cache.”	
  
...
JPA	
  Providers	
  Poll
A. Hibernate	
  
B. EclipseLink	
  
C. OpenJPA	
  
D. DataNuclues	
  
E. Other
• Second	
  Level	
  Cache	
  
• Persistence	
  Unit	
  
• EnXtyManagerFactory	
  
• Thread-­‐safe,	
  shared	
  
• Availa...
EnXtyManagerFactory
EntityManagerFactory
creates
creates
creates2LC
EntityManager
1LC
EntityManager
1LC
EntityManager
1LC
Puzzle	
  #1
em.getTransaction().begin();

Employee employee = em.find(Employee.class, 2L);

employee.getAddress().size();...
Loading
EntityManager
Factory
2LC
EntityManager
1LC
load from 1LC load from 2LC
select from
database
NOT FOUND NOT FOUND
F...
Puzzle	
  #1
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Employee employee = em.find(Emplo...
Puzzle	
  #1
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Employee employee = em.find(Emplo...
Puzzle	
  #2
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();

Employee employee = em1.find(Em...
Puzzle	
  #2
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();

Employee employee = em1.find(Em...
Puzzle	
  #3	
  (2LC	
  Configured,	
  
Hibernate)
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().beg...
Puzzle	
  #3	
  (2LC	
  Configured,	
  
Hibernate)
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().beg...
Puzzle	
  #4	
  (2LC	
  Configured!)
em1.getTransaction().begin();

Employee employee = em1.find(Employee.class, 2L);

emp...
Puzzle	
  #4	
  (2LC	
  Configured!)
em1.getTransaction().begin();

Employee employee = em1.find(Employee.class, 2L);

emp...
persistence.xml
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

40
Programmatic	
  
Properties props = new Properties()
.add(“javax.persistence.sharedCache.mode”, “ENABLE_SELECTIVE”);
Entit...
JPA	
  Cache	
  Modes
• ALL	
  
• All	
  enXty	
  data	
  is	
  stored	
  in	
  the	
  second-­‐level	
  cache	
  for	
  t...
JPA	
  Cache	
  Modes
• ALL	
  
• All	
  enXty	
  data	
  is	
  stored	
  in	
  the	
  second-­‐level	
  cache	
  for	
  t...
@Cachable
@Entity

@Cacheable

public class Employee {

}
@Entity

@Cacheable(true)

public class Employee {

}
@Entity

@...
@Cacheable
• @Cacheable	
  ignored	
  for	
  ALL	
  or	
  NONE
Cache	
  Retrieval	
  and	
  Store	
  
Modes
• Cache	
  Retrieval	
  Modes	
  
• javax.persistence.CacheRetrieveMode	
  
•...
Cache	
  Retrieval	
  and	
  Store	
  
EntityManager em = ...;
em.setProperty("javax.persistence.cache.storeMode", “BYPASS...
Programmatic	
  Access	
  to	
  Cache
EntityManager em = ...;
Cache cache = em.getEntityManagerFactory().getCache();
if (c...
Forget	
  that!
• Don’t	
  use	
  cache	
  retrieval	
  and	
  store	
  modes	
  
• Don’t	
  use	
  programmaXc	
  access	...
Hibernate	
  Caches
Hibernate	
  Caches
• First	
  Level	
  Cache	
  
• Second	
  Level	
  Cache	
  
• hydrated	
  or	
  disassembled	
  enXXe...
Hibernate	
  Cache	
  ConfiguraXon
• hibernate.cache.use_second_level_cache	
  
• Enable	
  or	
  disable	
  second	
  leve...
Hibernate	
  Cache	
  ConfiguraXon
• hibernate.cache.use_minimal_puts	
  
• OpXmizes	
  second-­‐level	
  cache	
  operaXon...
Hibernate	
  Cache	
  ConfiguraXon
• hibernate.cache.use_structured_entries	
  
• If	
  true,	
  forces	
  Hibernate	
  to	...
Cache	
  Concurrency	
  Strategy
• Global	
  cache	
  concurrency	
  strategy	
  
• hibernate.cache.default_cache_concurre...
Cache	
  Concurrency	
  Strategies
• read-­‐only	
  
• ApplicaXon	
  read-­‐only	
  data	
  
• Allows	
  deletes	
  
• rea...
Example	
  –	
  Entity	
  and	
  Collection	
  
Cache@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConc...
Example	
  -­‐	
  Query	
  Cache
List<Employee> employees = entityManager.createQuery(
"select e " +
"from Employee e " +
...
Puzzle	
  #2
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();

Employee employee = em1.find(Em...
find,	
  no	
  collecXon	
  caching
Local DB
(ping: ~0.05ms)
North California
(ping: ~38ms)
EU Frankfurt
(ping: ~420ms)
No ...
find,	
  collecXon	
  caching
Local DB
(ping: ~0.05ms)
North California
(ping: ~38ms)
EU Frankfurt
(ping: ~420ms)
No cache ...
Puzzle	
  #2/P6Spy
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();

Employee employee = em1.f...
Available	
  Hibernate	
  2nd	
  Level	
  
Cache	
  ImplementaXons
• EHCache	
  
• Infinispan	
  
• Hazelcast
Infinispan	
  Configuration	
  (Local)
<!-- This configuration is suitable for non-clustered environments, where only sing...
Infinispan	
  Configuration	
  
(Clustered)<jgroups>

<stack-file name="hibernate-jgroups" path="${hibernate.cache.infinis...
Guidelines
• Cache	
  as	
  much	
  as	
  you	
  can	
  
• As	
  much	
  RAM	
  you	
  have	
  
• Do	
  it	
  wisely	
  
•...
EclipseLink
• 2LC	
  enabled	
  by	
  default	
  
• CollecXon	
  caching	
  
• Query	
  caching	
  
• @org.eclipse.persist...
Conclusion
A	
  fool	
  with	
  a	
  tool	
  is	
  only	
  a	
  fool!
ConXnuous	
  Learning	
  
Please,	
  vote!	
  :)
Q&A
• patrycja@yonita.com	
  
• @yonlabs
Upcoming SlideShare
Loading in …5
×

Second Level Cache in JPA Explained

680 views

Published on

JavaOne 2016

Published in: Technology

Second Level Cache in JPA Explained

  1. 1. Second-­‐Level  Cache     in  JPA  Explained Patrycja  Wegrzynowicz   CTO,  Yonita,  Inc.   JavaOne  2016
  2. 2. About  Me • 15+  professional  experience     • SoPware  engineer,  architect,  head  of   soPware  R&D     • Author  and  speaker     • JavaOne,  Devoxx,  JavaZone,   TheServerSide  Java  Symposium,  Jazoon,   OOPSLA,  ASE,  others     • Top  10  Women  in  Tech  2016  in  Poland   • Founder  and  CTO  of  Yonita   • Automated  detecXon  and  refactoring  of   soPware  defects   • Trainings  and  code  reviews   • Security,  performance,  concurrency,   databases     • TwiYer  @yonlabs  
  3. 3. About  Me • 15+  professional  experience     • SoPware  engineer,  architect,  head  of   soPware  R&D     • Author  and  speaker     • JavaOne,  Devoxx,  JavaZone,   TheServerSide  Java  Symposium,  Jazoon,   OOPSLA,  ASE,  others     • Top  10  Women  in  Tech  2016  in  Poland   • Founder  and  CTO  of  Yonita   • Automated  detecXon  and  refactoring  of   soPware  defects   • Trainings  and  code  reviews   • Security,  performance,  concurrency,   databases     • TwiYer  @yonlabs  
  4. 4. Agenda • Why  cacheing  is  important?   • 1st  Level  Cache  and  2nd  Level  Cache   • JPA  configuraXon  parameters  for  cache   • JPA  API  for  cache   • Hibernate  2nd  Level  Cache   • EclipseLink  2nd  Level  Cache  (a  bit)
  5. 5. Databases
  6. 6. Databases
  7. 7. Performance
  8. 8. Request  Handling
  9. 9. Performance:  Throughput
  10. 10. Performance:  ExecuXon  Time
  11. 11. Performance:  Latency
  12. 12. Performance:  Response  Time
  13. 13. Example
  14. 14. Employee  Entity @Entity public class Employee {
 @Id @GeneratedValue private Long id;
 private String firstName; 
 private String lastName;
 private BigDecimal salary;
 @OneToOne @JoinColumn(name = "address_id")
 private Address address;
 @Temporal(TemporalType.DATE)
 private Date startDate;
 @Temporal(TemporalType.DATE)
 private Date endDate; 
 @ManyToOne @JoinColumn(name = "manager_id")
 private Employee manager; // …
 } 14
  15. 15. Sum  of  Salaries  By  Country
 Select  All  (1) TypedQuery<Employee> query = em.createQuery( "SELECT e FROM Employee e", Employee.class); List<Employee> list = query.getResultList();
 // calculate sum of salaries by country // map: country->sum Map<String, BigDecimal> results = new HashMap<>();
 for (Employee e : list) {
 String country = e.getAddress().getCountry();
 BigDecimal total = results.get(country);
 if (total == null) total = BigDecimal.ZERO;
 total = total.add(e.getSalary());
 results.put(country, total);
 }
 15
  16. 16. Sum  of  Salaries  by  Country
 Select  Join  Fetch  (2) TypedQuery<Employee> query = em.createQuery( "SELECT e FROM Employee e JOIN FETCH e.address", Employee.class);
 List<Employee> list = query.getResultList();
 // calculate sum of salaries by country // map: country->sum Map<String, BigDecimal> results = new HashMap<>();
 for (Employee e : list) {
 String country = e.getAddress().getCountry();
 BigDecimal total = results.get(country);
 if (total == null) total = BigDecimal.ZERO;
 total = total.add(e.getSalary());
 results.put(country, total);
 }
 16
  17. 17. Sum  of  Salaries  by  Country
 Projection  (3) Query query = em.createQuery( "SELECT e.salary, e.address.country FROM Employee e");
 List<Object[]> list = (List<Object[]>) query.getResultList();
 // calculate sum of salaries by country // map: country->sum Map<String, BigDecimal> results = new HashMap<>();
 for (Object[] e : list) {
 String country = (String) e[1];
 BigDecimal total = results.get(country);
 if (total == null) total = BigDecimal.ZERO;
 total = total.add((BigDecimal) e[0]);
 results.put(country, total);
 }
 17
  18. 18. Sum  of  Salaries  by  Country
 Aggregation  JPQL  (4) Query query = em.createQuery( "SELECT SUM(e.salary), e.address.country FROM Employee e GROUP BY e.address.country"); List<Object[]> list = (List<Object[]>) query.getResultList();
 // already calculated!
 18
  19. 19. Comparison  1-­‐4  (Hibernate)   100000  Employees,  Different  DB  LocaXons Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) (1) Select All (N+1) 26756ms 2-3 hours ~1 day (2) Select Join Fetch (3) Projection (4) Aggregation JPQL
  20. 20. Comparison  1-­‐4   100000  Employees,  Different  DB  LocaXons Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) (1) Select All (N+1) 26756ms 2-3 hours ~1 day (2) Select Join Fetch 4854ms 18027ms 25096ms (3) Projection (4) Aggregation JPQL
  21. 21. Comparison  1-­‐4   100000  Employees,  Different  DB  LocaXons Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) (1) Select All (N+1) 26756ms 2-3 hours ~1 day (2) Select Join Fetch 4854ms 18027ms 25096ms (3) Projection 653ms 2902ms 5006ms (4) Aggregation JPQL
  22. 22. Comparison  1-­‐4   100000  Employees,  Different  DB  LocaXons Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) (1) Select All (N+1) 26756ms 2-3 hours ~1 day (2) Select Join Fetch 4854ms 18027ms 25096ms (3) Projection 653ms 2902ms 5006ms (4) Aggregation JPQL 182ms 353ms 1198ms
  23. 23. Performance  Tuning:  Data • Get  your  data  in  bigger  chunks     • Many  small  queries  =>  many  round-­‐trips  =>  huge  extra  Xme  on   transport  =>  high  latency   • Move  your  data  closer  to  the  processing  place   • Large  distance  to  data  =>  long  round-­‐trip  =>  high  latency   • Don’t  ask  about  the  same  data  many  Xmes   • Extra  processing  Xme  +  extra  transport  Xme Cache
  24. 24. Cache  is  Everywhere Web Cache Application Cache RDBMS Cache DNS Cache OS Files Cache
  25. 25. Second  Level  Cache  in   JPA
  26. 26. JPA  Spec • “Persistence  providers  are  not  required  to  support  a   second-­‐level  cache.”   • “Portable  applicaXons  should  not  rely  on  support  by   persistence  providers  for  a  second-­‐level  cache.”
  27. 27. JPA  Providers  Poll A. Hibernate   B. EclipseLink   C. OpenJPA   D. DataNuclues   E. Other
  28. 28. • Second  Level  Cache   • Persistence  Unit   • EnXtyManagerFactory   • Thread-­‐safe,  shared   • Available  for  many  en1ty   managers  from  one  en1ty   manager  factory   • Provider  specific  support JPA  Caches • First  Level  Cache   • Persistence  Context   • EnXtyManager   • Not  thread-­‐safe   • Available  for  many   transac1ons  on  one  en1ty   manager   • Always
  29. 29. EnXtyManagerFactory EntityManagerFactory creates creates creates2LC EntityManager 1LC EntityManager 1LC EntityManager 1LC
  30. 30. Puzzle  #1 em.getTransaction().begin();
 Employee employee = em.find(Employee.class, 2L);
 employee.getAddress().size(); Employee another = em.find(Employee.class, 2L);
 em.getTransaction().commit();
 (A) No cache used (B) First Level Cache Used (C) Second Level Cache Used (D) None of the above 30
  31. 31. Loading EntityManager Factory 2LC EntityManager 1LC load from 1LC load from 2LC select from database NOT FOUND NOT FOUND FOUND FOUND RESULT FIND
  32. 32. Puzzle  #1 EntityManager em = emf.createEntityManager(); em.getTransaction().begin();
 Employee employee = em.find(Employee.class, 2L);
 employee.getAddress().size(); Employee another = em.find(Employee.class, 2L);
 em.getTransaction().commit();
 (A) No cache used (B) First Level Cache Used (C) Second Level Cache Used (D) None of the above 32
  33. 33. Puzzle  #1 EntityManager em = emf.createEntityManager(); em.getTransaction().begin();
 Employee employee = em.find(Employee.class, 2L);
 employee.getAddress().size(); Employee another = em.find(Employee.class, 2L);
 em.getTransaction().commit();
 (A) No cache used (B) First Level Cache Used (C) Second Level Cache Used (D) None of the above 33
  34. 34. Puzzle  #2 EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 34
  35. 35. Puzzle  #2 EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 35
  36. 36. Puzzle  #3  (2LC  Configured,   Hibernate) EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 36
  37. 37. Puzzle  #3  (2LC  Configured,   Hibernate) EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 37
  38. 38. Puzzle  #4  (2LC  Configured!) em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
a em2.getTransaction().begin();
 TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id=:id", Employee.class); q.setParameter("id", 2l);
 Employee employee = q.getSingleResult(); employee.getAddress().size(); em2.getTransaction().commit(); 
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 38
  39. 39. Puzzle  #4  (2LC  Configured!) em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
a em2.getTransaction().begin();
 TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id=:id", Employee.class); q.setParameter("id", 2l);
 Employee employee = q.getSingleResult(); employee.getAddress().size(); em2.getTransaction().commit(); 
 (A) No cache used (B) First Level Cache used (C) Second Level Cache used (D) None of the above 39
  40. 40. persistence.xml <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
 40
  41. 41. Programmatic   Properties props = new Properties() .add(“javax.persistence.sharedCache.mode”, “ENABLE_SELECTIVE”); EntityManagerFactor emf = Persistence .createEntityManagerFactory(“test-pu”, props); 41
  42. 42. JPA  Cache  Modes • ALL   • All  enXty  data  is  stored  in  the  second-­‐level  cache  for  this  persistence  unit.     • NONE     • No  data  is  cached  in  the  persistence  unit.  The  persistence  provider  must  not  cache  any   data.   • ENABLE_SELECTIVE     • Enable  caching  for  enXXes  that  have  been  explicitly  set  with  the  @Cacheable  annotaXon.   • DISABLE_SELECTIVE     • Enable  caching  for  all  enXXes  except  those  that  have  been  explicitly  set  with  the   @Cacheable(false)  annotaXon.     • UNSPECIFIED     • The  caching  behavior  for  the  persistence  unit  is  undefined.  The  persistence  provider’s   default  caching  behavior  will  be  used.
  43. 43. JPA  Cache  Modes • ALL   • All  enXty  data  is  stored  in  the  second-­‐level  cache  for  this  persistence  unit.     • NONE     • No  data  is  cached  in  the  persistence  unit.  The  persistence  provider  must  not  cache  any   data.   • ENABLE_SELECTIVE     • Enable  caching  for  enXXes  that  have  been  explicitly  set  with  the  @Cacheable  annotaXon.   • DISABLE_SELECTIVE     • Enable  caching  for  all  enXXes  except  those  that  have  been  explicitly  set  with  the   @Cacheable(false)  annotaXon.     • UNSPECIFIED     • The  caching  behavior  for  the  persistence  unit  is  undefined.  The  persistence  provider’s   default  caching  behavior  will  be  used.
  44. 44. @Cachable @Entity
 @Cacheable
 public class Employee {
 } @Entity
 @Cacheable(true)
 public class Employee {
 } @Entity
 @Cacheable(false)
 public class Address {
 } 44
  45. 45. @Cacheable • @Cacheable  ignored  for  ALL  or  NONE
  46. 46. Cache  Retrieval  and  Store   Modes • Cache  Retrieval  Modes   • javax.persistence.CacheRetrieveMode   • USE  (default)   • BYPASS   • Cache  Store  Modes   • javax.persistence.storeMode   • USE  (default)   • the  cache  data  is  created  or  updated  when  data  is  read  from  or  commiYed  to   • when  data  is  already  in  the  cache,  no  refresh  on  read   • REFRESH   • forced  refresh  on  read   • BYPASS
  47. 47. Cache  Retrieval  and  Store   EntityManager em = ...; em.setProperty("javax.persistence.cache.storeMode", “BYPASS"); Map<String, Object> props = new HashMap<String, Object>(); props.put("javax.persistence.cache.retrieveMode", "BYPASS"); Employee employee = = em.find(Employee.class, 1L, props); TypedQuery<Employee> q = em.createQuery(cq); q.setHint("javax.persistence.cache.storeMode", "REFRESH"); 47
  48. 48. Programmatic  Access  to  Cache EntityManager em = ...; Cache cache = em.getEntityManagerFactory().getCache(); if (cache.contains(Employee.class, 1L)) { // the data is cached } else { // the data is NOT cached } Cache interface methods: boolean contains(Class cls, Object primaryKey) void evict(Class cls) void evict(Class cls, Object primaryKey) void evictAll() <T> T unwrap(Class<T> cls) 48
  49. 49. Forget  that! • Don’t  use  cache  retrieval  and  store  modes   • Don’t  use  programmaXc  access  to  2LC   • Use  provider-­‐specific  configuraXon!
  50. 50. Hibernate  Caches
  51. 51. Hibernate  Caches • First  Level  Cache   • Second  Level  Cache   • hydrated  or  disassembled  enXXes:  EnXtyEntry   • collecXons   • Query  Cache
  52. 52. Hibernate  Cache  ConfiguraXon • hibernate.cache.use_second_level_cache   • Enable  or  disable  second  level  caching  overall.     • Default  is  true   • hibernate.cache.region.factory_class   • Default  region  factory  is  NoCachingRegionFactory   • hibernate.cache.use_query_cache   • Enable  or  disable  second  level  caching  of  query  results.     • Default  is  false.   • hibernate.cache.query_cache_factory
  53. 53. Hibernate  Cache  ConfiguraXon • hibernate.cache.use_minimal_puts   • OpXmizes  second-­‐level  cache  operaXons  to  minimize  writes,  at  the   cost  of  more  frequent  reads.  Providers  typically  set  this  appropriately.   • hibernate.cache.default_cache_concurrency_strategy   • In  Hibernate  second-­‐level  caching,  all  regions  can  be  configured   differently  including  the  concurrency  strategy  to  use  when  accessing   that  parXcular  region.  This  sevng  allows  to  define  a  default  strategy   to  be  used.   • Providers  specify  this  sevng!
  54. 54. Hibernate  Cache  ConfiguraXon • hibernate.cache.use_structured_entries   • If  true,  forces  Hibernate  to  store  data  in  the  second-­‐level  cache  in  a  more   human-­‐friendly  format.     • Default:  false   • hibernate.cache.auto_evict_collecXon_cache   • Enables  or  disables  the  automaXc  evicXon  of  a  bidirecXonal  associaXon’s   collecXon  cache  entry  when  the  associaXon  is  changed  just  from  the  owning   side.   • Default:  false   • hibernate.cache.use_reference_entries   • Enable  direct  storage  of  enXty  references  into  the  second  level  cache  for   read-­‐only  or  immutable  enXXes.
  55. 55. Cache  Concurrency  Strategy • Global  cache  concurrency  strategy   • hibernate.cache.default_cache_concurrency_strategy   • Hibernate  @Cache  annotaXon  on  an  enXty  level   • usage:  defines  the  CacheConcurrencyStrategy   • region:  defines  a  cache  region  where  entries  will  be  stored   • include:  if  lazy  properXes  should  be  included  in  the  second  level   cache.  Default  value  is  "all",  so  lazy  properXes  are  cacheable.  The   other  possible  value  is  "non-­‐lazy",  so  lazy  properXes  are  not   cacheable.
  56. 56. Cache  Concurrency  Strategies • read-­‐only   • ApplicaXon  read-­‐only  data   • Allows  deletes   • read-­‐write   • ApplicaXon  updates  data   • Consistent  access  to  a  single  enXty,  but  not  a  serializable  transacXon  isolaXon   level   • nonstrict-­‐read-­‐write   • Occasional  stale  reads   • transacXonal   • Provides  serializable  transacXon  isolaXon  level
  57. 57. Example  –  Entity  and  Collection   Cache@Entity @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Employee { @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL) @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) private Set<Phone> phones = new HashSet<>(); } // cache used! Person person = entityManager.find(Employee.class, 1L); // cache used! Person person = entityManager.find(Employee.class, 1L); person.getPhones().size(); 57
  58. 58. Example  -­‐  Query  Cache List<Employee> employees = entityManager.createQuery( "select e " + "from Employee e " + "where e.firstName = :firstName", Employee.class) .setParameter( "firstName", "John") .setHint("org.hibernate.cacheable", "true") .getResultList(); 58
  59. 59. Puzzle  #2 EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 59
  60. 60. find,  no  collecXon  caching Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) No cache 87ms 186ms 1164ms Cached 62ms 127ms 995ms
  61. 61. find,  collecXon  caching Local DB (ping: ~0.05ms) North California (ping: ~38ms) EU Frankfurt (ping: ~420ms) No cache 82ms 162ms 1178ms Cached 3ms 98ms 941ms
  62. 62. Puzzle  #2/P6Spy EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin();
 Employee employee = em1.find(Employee.class, 2L);
 employee.getAddress().size(); em1.getTransaction().commit();
 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin();
 Employee employee = em2.find(Employee.class, 2L);
 employee.getAddress().size(); em2.getTransaction().commit();
 62
  63. 63. Available  Hibernate  2nd  Level   Cache  ImplementaXons • EHCache   • Infinispan   • Hazelcast
  64. 64. Infinispan  Configuration  (Local) <!-- This configuration is suitable for non-clustered environments, where only single instance accesses the DB -->
 <cache-container name="SampleCacheManager" statistics="false" default-cache="the-default-cache" shutdown-hook="DEFAULT">
 <jmx duplicate-domains="true"/>
 
 <local-cache-configuration name="the-default-cache" statistics="false" />
 
 <!-- Default configuration is appropriate for entity/collection caching. -->
 <local-cache-configuration name="entity" simple-cache="true" statistics="false" statistics-available="false">
 <transaction mode="NONE" />
 <eviction max-entries="10000" strategy="LRU"/>
 <expiration max-idle="100000" interval="5000"/>
 </local-cache-configuration>
 
 <!-- A config appropriate for query caching. Does not replicate queries. -->
 <local-cache-configuration name="local-query" simple-cache="true" statistics="false" statistics-available="false">
 <transaction mode="NONE" />
 <eviction max-entries="10000" strategy="LRU"/>
 <expiration max-idle="100000" interval="5000"/>
 </local-cache-configuration>
 
 <local-cache-configuration name="timestamps" simple-cache="true" statistics="false" statistics-available="false">
 <locking concurrency-level="1000" acquire-timeout="15000"/>
 <!-- Explicitly non transactional -->
 <transaction mode="NONE"/>
 <!-- Don't ever evict modification timestamps -->
 <eviction strategy="NONE"/>
 <expiration interval="0"/>
 </local-cache-configuration>
 
 <!-- When providing custom configuration, always make this cache local and non-transactional.
 64
  65. 65. Infinispan  Configuration   (Clustered)<jgroups>
 <stack-file name="hibernate-jgroups" path="${hibernate.cache.infinispan.jgroups_cfg:default-configs/default-jgroups-tcp.xml}"/>
 </jgroups>
 <cache-container name="SampleCacheManager" statistics="false" default-cache="the-default-cache" shutdown-hook="DEFAULT">
 <transport stack="hibernate-jgroups" cluster="infinispan-hibernate-cluster"/>
 <jmx duplicate-domains="true"/>
 
 <local-cache-configuration name="the-default-cache" statistics="false" />
 
 <!-- Default configuration is appropriate for entity/collection caching. -->
 <invalidation-cache-configuration name="entity" mode="SYNC" remote-timeout="20000" statistics="false" statistics-available="false">
 <locking concurrency-level="1000" acquire-timeout="15000"/>
 <transaction mode="NONE" />
 <eviction max-entries="10000" strategy="LRU"/>
 <expiration max-idle="100000" interval="5000"/>
 </invalidation-cache-configuration>
 
 <!-- A config appropriate for query caching. Does not replicate queries. -->
 <local-cache-configuration name="local-query" statistics="false" statistics-available="false">
 <locking concurrency-level="1000" acquire-timeout="15000"/>
 <transaction mode="NONE" />
 <eviction max-entries="10000" strategy="LRU"/>
 <expiration max-idle="100000" interval="5000"/>
 </local-cache-configuration>
 
 <!-- A query cache that replicates queries. Replication is asynchronous. -->
 <replicated-cache-configuration name="replicated-query" mode="ASYNC" statistics="false" statistics-available="false">
 <locking concurrency-level="1000" acquire-timeout="15000"/>
 <transaction mode="NONE" />
 <eviction max-entries="10000" strategy="LRU"/>
 <expiration max-idle="100000" interval="5000"/>
 </replicated-cache-configuration>
 
 <!-- Optimized for timestamp caching. A clustered timestamp cache
 is required if query caching is used, even if the query cache
 itself is configured with CacheMode=LOCAL. -->
 65
  66. 66. Guidelines • Cache  as  much  as  you  can   • As  much  RAM  you  have   • Do  it  wisely   • Read-­‐only  data   • Almost  read-­‐only  data   • More  reads  than  writes   • Hit  raXo
  67. 67. EclipseLink • 2LC  enabled  by  default   • CollecXon  caching   • Query  caching   • @org.eclipse.persistence.annotaXons.Cache   • type:  type  of  the  cache  (FULL,  WEAK,  SOFT,  SOFT_WEAK,  HARD_WEAK)   • size:  number  of  objects   • isolaXon:  shared,  isolated,  protected   • expiry   • expiryTimeOfDay   • alwaysRefresh   • refreshOnlyIfNewer   • disableHits   • coordinaXonType   • databaseChangeNoXficaXonType
  68. 68. Conclusion
  69. 69. A  fool  with  a  tool  is  only  a  fool!
  70. 70. ConXnuous  Learning  
  71. 71. Please,  vote!  :)
  72. 72. Q&A • patrycja@yonita.com   • @yonlabs

×