2011-03-24 5 views
3

많은 관계가 있습니다. 사용자에게 회사가 있다고 가정 해 봅시다. 회사 엔티티는 다른 관계가 없습니다.최대 절전 모드 2 차 레벨 캐시 문제

Company의 findAll Hibernate 쿼리에 대한 두 번째 레벨 캐시를 활성화하면 두 번째로 페이지를 다시로드합니다. 즉, 사용자가로드되고 모든 회사의 목록이로드됨을 의미합니다. 기존의 각 회사를 선택합니다 (select. .. id =?) 회사에서 최대 절전 모드 출력. 내가 읽기 전용 전략 제이 보스 TreeCacheProvider을 사용하고

return (List<T>) getHibernateTemplate().execute(new HibernateCallback() { 

      public Object doInHibernate(Session session) 
        throws HibernateException, SQLException { 
       Criteria c = session.createCriteria(persistentClass); 
       c.setCacheable(cacheFindAll); 

       return c.list(); 
      } 
     }); 

: 회사에 대한 findall은을 호출 할 때이 문제가 발생 , 그것은 (이 적절한 유형으로 확장되는 클래스의 일반적인 방법입니다) 다음과 같습니다. setCacheable(false)을 사용하면 "원하지 않는"선택 항목이 없습니다.

왜 이런 일이 발생하며 어떻게 이러한 동작을 제거 할 수 있습니까?

답변

6

setCacheable()쿼리 캐시을 가능하게하기위한 것이다 전화, javadoc를 참조하십시오

Enable caching of this query result, provided query caching is enabled for the underlying session

은 무슨 일 회사의 ID가 개체 자체를 캐시하지만,하지 않는 것입니다. 두 번째 수준 캐시를 사용하도록 설정하면 이러한 개별 회사 쿼리가 두 번째 수준 캐시에 의해 처리됩니다.

두 번째 레벨 캐시를 사용하려면 persistence.xml에서 hibernate.cache.use_second_level_cache = true를 설정해야합니다. 또한 두 번째 레벨 캐시에서 캐시하려는 관계와 엔티티에 주석을 달아야합니다.

@OneToMany 
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 
private List<Company> companies; 

그리고 개체 캐싱 :

@Entity 
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 
public class Company { 
    ... 
} 

이 BTW 두 번째 레벨 캐시는 캐시 관계 기관 당신이 ID를 찾을 수 있습니다. 쿼리는 두 번째 레벨 캐시에서 캐시 할 수 없으며 항상 데이터베이스 (또는 쿼리 캐시)로 이동합니다.

+0

감사합니다. 예, 맞습니다. setCacheable이 쿼리 캐시를 설정합니다. 그러나 나는 왜 다중 선택이 일어나는지 이해하지 못한다. 그들은 setCacheable (true) 및 second level 캐시가 읽기 전용으로 설정되었을 때만 발생합니다. 트랜잭션으로 설정하면 발생하지 않습니다. 나는 또한 EHcache를 읽기 - 쓰기로 시도했지만 일어날 수 없다. 또한, 모두로드해야하는 엔티티를 캐시하는 방법이 있습니까? (예 : 국가 목록 등) – kane77

+0

EntityManager.createQuery ("회사"에서)를 수행하는 경우 getResultList(); 두 번째 레벨 캐시에 모든 회사가 있습니다. 그런 다음 회사 지연로드에 대한 모든 관계를 작성했는지 확인하고 쿼리에있는 회사를 참조하지 않으면 두 번째 레벨 캐시에서 항상 읽혀집니다 (즉, 캐시를 만료시키지 않으면 또는 오버플로). – Kdeveloper