Ran*_*ain 14 java hibernate jpa spring-data spring-data-jpa
我的应用程序使用JPA(1.2),Spring(3.1.2),Spring Data(1.1.0)和Hibernate(4.1.7).数据库:Oracle10g
我们启用了二级缓存.它与实体一起工作正常但它在命名查询缓存上创建了问题.
问题是:如果命名查询具有相同的where子句但是具有不同的select语句,那么无论第一个查询执行它还是为第二个查询提供相同的结果.
就像我的第一个查询(countRelease)一样
select count(r) from Release r where r.type in
(select c.contentTypeId from ContentType c where c.parentContentTypeId is NULL)
order by r.validityStart
Run Code Online (Sandbox Code Playgroud)
和第二个查询(findRelease)是
select r from Release r where r.type in
(select c.contentTypeId from ContentType c where c.parentContentTypeId is NULL)
order by r.validityStart
Run Code Online (Sandbox Code Playgroud)
如果先运行第一个查询,那么计数将会到来,之后如果我运行第二个查询,那么还会计数它应该给我发布实体的列表.
如果我删除查询缓存它工作正常,如果我在第二个查询where子句中进行一些更改,那么它也工作正常,但我不需要这样做.
我们如何解决这个问题?
我的Java代码
@Query(name="findRelease")
@QueryHints({@QueryHint(name = "org.hibernate.cacheRegion", value ="cvodrelease"),@QueryHint(name = "org.hibernate.cacheable", value ="true") })
public List<Release> findRelease();
@Query(name="countRelease")
@QueryHints({@QueryHint(name = "org.hibernate.cacheRegion", value ="cvodrelease"),@QueryHint(name = "org.hibernate.cacheable", value ="true") })
public Long countOfRelease(Date today);
Run Code Online (Sandbox Code Playgroud)
缓存配置
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
<property name="hibernate.cache.provider_configuration_file_resource_path" value="ehcache.xml" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="ehcache.xml" p:shared="true"/>
Run Code Online (Sandbox Code Playgroud)
查询缓存维护结果,其中查询与参数组合构成键和值作为标识符。
来自文档:
当数据缓存没有查询结果中某个 id 的任何缓存数据时,不使用缓存。
不会缓存导致自定义字段类型或 BigDecimal 或 BigInteger 字段投影的查询。
请注意,查询缓存不会缓存结果集中实际实体的状态;它仅缓存标识符值和值类型的结果。查询缓存应始终与二级缓存结合使用。
最好获取整个对象,而不是查询中的字段。
可能它忽略了查询的选择部分并缓存结果。后面的部分对于两个查询来说是相同的,因此产生相同的结果。您可以尝试更改查询执行顺序并观察结果。