我有一个带有Spring Data JPA(hibernate后端)存储库类的Spring Boot应用程序。我添加了几个自定义查找器方法,其中一些带有特定@Query注释,以告诉它如何获取数据。我已经为hibernate二级缓存设置了EhCache,但是到目前为止,获得这些结果缓存的唯一方法是启用hibernate查询缓存。我希望定义一个特定的缓存,并将实际的域对象存储在该缓存中,就像它是普通的查找程序一样。以下是我的回购代码:
@Query
public interface PromotionServiceXrefRepository extends PagingAndSortingRepository<PromotionServiceXref, Integer> { @Query("SELECT psx FROM Customer c " + "JOIN c.customerProductPromotions cpp " + "JOIN cpp.productPromotion pp " + "JOIN pp.promotion p JOIN p.promotionServiceXrefs psx " + "WHERE c.customerId = ?1") @QueryHints(@QueryHint(name = "org.hibernate.cacheable", value = "true")) @Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "promotionServiceXrefByCustomerId") Set<PromotionServiceXref> findByCustomerId(int customerId); }
这是我定义的未使用的“ promotionServiceXrefByCustomerId”缓存:
<cache name="promotionServiceXrefByCustomerId" overflowToDisk="true" diskPersistent="true" maxEntriesLocalHeap="3000000" eternal="true" diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LFU" transactionalMode="off" statistics="true"> </cache>
我究竟做错了什么?如果启用,StandardQueryCache则此数据将被缓存在那里,hibernate将不执行查询。但是当我禁用查询缓存时,不会被缓存。我在这里做错了什么?请帮忙!
StandardQueryCache
您拥有的代码无法正常工作的原因@Cache不是要这样工作。如果要缓存查询方法执行的结果,最简单的方法是使用Spring的缓存抽象。
@Cache
interface PromotionServiceXrefRepository extends PagingAndSortingRepository<PromotionServiceXref, Integer> { @Query("…") @Cacheable("servicesByCustomerId") Set<PromotionServiceXref> findByCustomerId(int customerId); @Override @CacheEvict(value = "servicesByCustomerId", key = "#p0.customer.id") <S extends PromotionServiceXref> S save(S service); }
此设置将导致呼叫结果findByCustomerId(…)由客户标识符缓存。请注意,我们@CacheEvict在覆盖的save(…)方法中添加了,这样,只要保存了实体,就将驱逐用查询方法填充的缓存。这可能也必须传播到delete(…)方法中。
findByCustomerId(…)
@CacheEvict
save(…)
delete(…)
现在,您可以继续进行专用配置CacheManager(有关详细信息,请参见参考文档),以插入您喜欢的任何缓存解决方案(ConcurrentHashMap在此处使用普通格式)。
CacheManager
ConcurrentHashMap
@Configuration @EnableCaching class CachingConfig { @Bean CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.addCaches(Arrays.asList(new ConcurrentMapCache("servicesByCustomerId))); return cacheManager; } }