사용자 도구

사이트 도구


java:hibernate:cache

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
java:hibernate:cache [2014/07/04 13:11]
kwon37xi [Entity Collection Cache]
java:hibernate:cache [2018/09/13 14:28] (현재)
kwon37xi
줄 6: 줄 6:
     * Memcached임에도 Region(namespace) 지원     * Memcached임에도 Region(namespace) 지원
   * [[https://github.com/debop/hibernate-redis|hibernate-redis]] Hibernate4 redis 구현체. 현재 Entity 클래스 변경에 대한 방어가 안 돼 있는 것으로 보임.   * [[https://github.com/debop/hibernate-redis|hibernate-redis]] Hibernate4 redis 구현체. 현재 Entity 클래스 변경에 대한 방어가 안 돼 있는 것으로 보임.
 +
 +===== Hibernate의 기본 캐시 전략 =====
 +  * Memcached 등의 외부 서버보다는 로컬 JVM에서 값을 즉시 읽을 수 있는 [[java:ehcache|ehcache]]나 [[java:infinispan|Infinispan]] 계통을 사용할 것.
 +  * [[http://infinispan.org/docs/6.0.x/user_guide/user_guide.html#_using_infinispan_as_jpa_hibernate_second_level_cache_provider|Infinispan 매뉴얼의 Hibernate 관련 절을 보면 Hibernate의 캐시 전략이 나옴]] -> 좀 더 자세히 읽어볼 것.
 +  * 기본적으로 Replication-Invalidation 전략을 사용한다.
 +  * [[java:ehcache|ehcache]] 사용시에
 +    * Entity와 컬렉션은 ''replicatePuts=false'', ''replicateUpdatesViaCopy=false''를 통해 네트워크 부하를 낮춘다. 이는 또한 여러 서버의 순차 배포시에 Class 버전이 서로 안 맞는 상황에서 직렬화 오류나는 것을 방어해준다. 비동기로 한다.
 +    * ''org.hibernate.cache.internal.StandardQueryCache''는 완전 local 캐시로만 적용한다.
 +    * ''org.hibernate.cache.spi.UpdateTimestampsCache''는 ''replicatePuts=true'', ''replicateUpdatesViaCopy=true'' 및 비동기방식을 통해 모든 서버가 일관성있고 동일한 값을 유지하게 한다. 또한 서버가 뜰때 다른 서버의 ''UpdateTimestampsCache''들을 복제해 와서 사용해야 한다.
  
 ===== Cuncurrency Strategy ===== ===== Cuncurrency Strategy =====
줄 21: 줄 30:
     * ''get'' : 캐시에서 읽어서 있으면 반환 한다.     * ''get'' : 캐시에서 읽어서 있으면 반환 한다.
   * 최초 데이터 가져온 후 캐시 생성   * 최초 데이터 가져온 후 캐시 생성
-    * ''putFromLoad'' : minimalPutOverride == true일 경우에는 이미 캐시에 값이 존재하면 현재 것을 버린다. 아니면 항상 값을 캐시에 쓴다. 캐시에 썼으면 ''return true;'' 아니면 ''return false;''. ''putFromLoad''는 데이터는 가져왔으나 캐시가 없었을 때 호출되는 것인데, 그 사이에 다른 쓰레드에서 캐시에 데이터를 썼다면 굳이 다시 쓸 필요는 없다.+    * ''putFromLoad''​ : minimalPutOverride == true일 경우에는 이미 캐시에 값이 존재하면 현재 것을 버린다. 아니면 항상 값을 캐시에 쓴다. 캐시에 썼으면 ''return true;''​ 아니면 ''return false;''. ''putFromLoad''는 데이터는 가져왔으나 캐시가 없었을 때 호출되는 것인데, 그 사이에 다른 쓰레드에서 캐시에 데이터를 썼다면 굳이 다시 쓸 필요는 없다.
   * 입력 : ''insert/afterInsert'' : 객체를 persist해도 호출하지 않음. 즉, persist시 캐싱 불가. ''return false;''   * 입력 : ''insert/afterInsert'' : 객체를 persist해도 호출하지 않음. 즉, persist시 캐싱 불가. ''return false;''
   * 수정 - 예외를 발생시켜야 한다.   * 수정 - 예외를 발생시켜야 한다.
줄 140: 줄 149:
  
 ===== Entity Collection Cache ===== ===== Entity Collection Cache =====
 +==== 기본 ====
 +
 엔티티의 컬렉션을 캐시하려면 해당 컬렉션에 ''@Cache'' 애노테이션을 붙여야 한다. 엔티티의 컬렉션을 캐시하려면 해당 컬렉션에 ''@Cache'' 애노테이션을 붙여야 한다.
 <code java> <code java>
줄 150: 줄 161:
 </code> </code>
  
-양방향 관계의 경우 명시적으로 Collection 쪽에 수정이 발생해야만 캐시가 갱신된다.+양방향 관계의 경우 **명시적으로 Collection 쪽에 수정이 발생**해야만 캐시가 갱신된다. 
 + 
 +==== OneToOne not owning size ==== 
 +  * OneToOne 관계의 not owning side(mappedBy를 명시한 부모측)에는 캐시가 걸리지 않는 것으로 보인다.[[https://forum.hibernate.org/viewtopic.php?f=1&t=976936|참조]] 
  
 ===== Query Cache ===== ===== Query Cache =====
줄 160: 줄 175:
 TypedQuery<Book> query = em.createNamedQuery("Book.byEdition", Book.class); TypedQuery<Book> query = em.createNamedQuery("Book.byEdition", Book.class);
 query.setParameter("edition", 3); query.setParameter("edition", 3);
- 
 query.setHint("org.hibernate.cacheable", true); query.setHint("org.hibernate.cacheable", true);
 +query.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
 query.setHint("org.hibernate.cacheRegion", "book-by-edition"); // region 지정 query.setHint("org.hibernate.cacheRegion", "book-by-edition"); // region 지정
 </code> </code>
줄 192: 줄 207:
 } }
 </code> </code>
 +
 +===== Evict All =====
 +현재 Hibernate는 모든 리젼(Region)을 ''evict''하려면 다음을 호출해야 한다.
 +<code java>
 +org.hibernate.Cache cache = sessionFactory.getCache();
 +cache.evictEntityRegions();
 +cache.evictQueryRegions();
 +cache.evictDefaultQueryRegion();
 +cache.evictCollectionRegions();
 +</code>
 +
 +===== Cache 관련 Properties =====
 +  * ''org.hibernate.cacheable'' Whether or not a query is cacheable ( eg. new Boolean(true) ), defaults to false
 +  * ''org.hibernate.cacheMode'' Override the cache mode for this query ( eg. CacheMode.REFRESH ) - [[https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/CacheMode.html|CacheMode]]
 +  * ''org.hibernate.cacheRegion'' Cache region of this query ( eg. new String("regionName") )
 +
 +===== Query 실행 후 Entity Cache 갱신 문제 =====
 +  * PK 기반 쿼리는 Cache에서 (있으면) 값을 가져오고, 쿼리 실행 후 필요하면 Cache에 값을 설정한다.
 +  * 하지만 Query 실행시에는 (Query Cache 가 꺼져 있으면) 쿼리 결과 Entity들을 다시 Cache에 넣는 일을 한다(''putFromLoad'').
 +  * ''minimalPutOverride=true''가 이를 방지하는 역할을 한다. 캐시 구현체가 ''minimalPutOverride''를 구현하지 않았을 수도 있다.
 +  * 하지만 ''minimalPutOverride''를 켜지 않았을 경우에는 ''org.hibernate.cacheMode=CacheMode.GET'' 혹은 그 외 값으로 통해 해당 쿼리에 대한 캐시 사용을 꺼버린다.
 +  * 
 +
 ===== 참조문서 ===== ===== 참조문서 =====
   * [[http://www.javalobby.org/java/forums/t48846.html|Hibernate: Truly Understanding the Second-Level and Query Caches]]   * [[http://www.javalobby.org/java/forums/t48846.html|Hibernate: Truly Understanding the Second-Level and Query Caches]]
줄 199: 줄 237:
   * [[http://www.devx.com/dbzone/Article/29685|Speed Up Your Hibernate Applications with Second-Level Caching]]   * [[http://www.devx.com/dbzone/Article/29685|Speed Up Your Hibernate Applications with Second-Level Caching]]
   * [[http://www.javabeat.net/introduction-to-hibernate-caching/|What is Hibernate Caching?]] : 동시성 전략에 대해 자세히 설명   * [[http://www.javabeat.net/introduction-to-hibernate-caching/|What is Hibernate Caching?]] : 동시성 전략에 대해 자세히 설명
 +  * [[http://learningviacode.blogspot.in/2013/08/cachemodes-in-hibernate.html|Learning the code way: CacheModes in Hibernate]]
 +  * [[http://blogs.innovationm.com/spring-hibernate-with-ehcache/|Spring Hibernate With EhCache | InnovationM Blog]]
 +  * [[https://www.baeldung.com/hibernate-second-level-cache|Hibernate Second Level Cache]]
java/hibernate/cache.1404447115.txt.gz · 마지막으로 수정됨: 2014/07/04 13:11 저자 kwon37xi