当前位置: 首页 > 知识库问答 >
问题:

JPA Spring Hibernate DBUnit:可缓存查询:如何强制重新加载?

汪玮
2023-03-14

我试图将我的项目设置为在jUnit模式下使用Spring hibernate和Spring hibernate JTA(Glassfish)的缓存(ehache)。

这里是我的junit的spring hiberrnate配置

<bean id="cacheManager" 
    class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="springEhcache"/>
</bean>
<bean id="springEhcache" 
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="cacheManagerName" value="method-cache" />
</bean>

<!-- Config Database: ImageManager -->
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="/jdbc.properties" />

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
    p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
    p:password="${jdbc.password}" />


<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.generate_statistics">true</prop>
            <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
            <prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
        </props>
    </property>
</bean>

<tx:annotation-driven />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean> 

我用@缓存注释了一些实体(我想要缓存的唯一实体)

@Cacheable
@Entity
@Table(name = "PLATFORM")
public class Plaform ...

我设置了一些查询:setCacheable(true)。

@Transactional(readOnly = true)
    public List<Platform> listPlatform() {
        return sessionFactory.getCurrentSession().createQuery("from Platform").setCacheable(true).list();
    }

我有一个对象(名为CacheMap)带有@PostConstruct

这将加载一些查询并填充一些映射。

当我使用junit时,我的CacheMap对象将获取一些数据,然后DBUnit将插入一组数据。

问题是当我调用listPlatform时,它返回空,因为该查询首先被称为我的CacheMap。有一种方法可以告诉Hibernate使当前缓存无效?

编辑:

我在insert之后通过DBunit添加了这段代码,但当我重新运行查询时,返回的是缓存的值。

for (String name : cacheManager.getCacheNames()) {
    cacheManager.getCache(name).clear();
}

编辑2。我删除了建议的行,并将其替换为

sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();

从我的配置中删除Spring缓存,现在它可以用于查询,但缓存级别2中没有实体。我将继续测试并发布完整的解决方案

这里的统计数据:

无缓存统计信息=统计信息[开始时间=1388275898144,打开的会话=16,关闭的会话=16,事务=32,成功的事务=16,乐观锁失败=0,刷新=87,获得的连接=16,准备的语句=1518,关闭的语句=1518,二级缓存放置=0,二级缓存命中=0,加载的实体=943,更新的实体=3,插入的实体]rted=334,删除的实体=0,取回的实体=64,加载的集合=459,更新的集合=149,删除的集合=0,重新创建的集合=200,取回的集合=459,对数据库执行的查询=422,查询缓存放置=0,查询缓存命中=0,查询缓存未命中=0,最大查询时间=321]

使用CACHE统计=统计[开始时间=1388275940458,打开的会话=16,关闭的会话=16,事务=32,成功的事务=16,乐观锁失败=0,刷新=84,获得的连接=16,准备的语句=1341,关闭的语句=1341,二级缓存放置=0,二级缓存命中=0,二级缓存未命中=0,实体加载=841,实体更新=3,实体插入=334,实体删除=0,实体提取=93,集合加载=403,集合更新=149,集合删除=0,集合重新创建=200,集合提取=293,查询执行到数据库=382,查询缓存放置=231,查询缓存命中=40,查询缓存未命中=231,最大查询时间=137]

编辑3:

我发现如何缓存实体到二级缓存。当我缓存实体时,它似乎变慢了。

缓存:读写统计=统计[开始时间=1388278575470,打开的会话=16,关闭的会话=16,事务=32,成功的事务=16,乐观锁失败=0,刷新=84,获得的连接=16,准备的语句=1377,关闭的语句=1377,二级缓存放置=37,二级缓存命中=77,二级缓存未命中=2,实体加载=764,实体更新=3,实体插入=334,实体删除=0,实体提取=38,集合加载=403,集合更新=149,集合删除=0,集合重新创建=200,集合提取=403,查询执行到数据库=363,查询缓存放置=233,查询缓存命中=59,查询缓存未命中=233,最大查询时间=161]

无实体缓存统计信息=统计信息[开始时间=1388278655759,打开的会话=16,关闭的会话=16,事务=32,成功的事务=16,乐观锁失败=0,刷新=84,获得的连接=16,准备的语句=1333,关闭的语句=1333,二级缓存放置=0,二级缓存命中=0,加载的实体=841,更新的实体=3,插入的实体]rted=334,删除的实体=0,获取的实体=104,加载的集合=403,更新的集合=149,删除的集合=0,重新创建的集合=200,获取的集合=293,对数据库执行的查询=363,查询缓存放置=233,查询缓存命中=59,查询缓存未命中=233,最大查询时间=147]

这里是我的ehcache.xml

<ehcache>
    <diskStore path="./resource"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU"
    />

    <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="20"
        eternal="false"
        timeToLiveSeconds="120"
        overflowToDisk="false"/>

    <cache name="org.hibernate.cache.UpdateTimestampsCache"
        maxElementsInMemory="1000"
        eternal="true"
        overflowToDisk="false"/>
</ehcache>

这是我的pom(它的一部分)

<properties>
    <spring.version>3.2.5.RELEASE</spring.version>
    <hibernate.version>3.6.9.Final</hibernate.version>
</properties>

<!-- Spring 3 dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.6</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-annotations</artifactId>
    <version>3.5.6-Final</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.dbunit</groupId>
    <artifactId>dbunit</artifactId>
    <version>2.4.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.xbean</groupId>
    <artifactId>xbean-spring</artifactId>
    <version>3.7</version>
</dependency>

共有2个答案

董和泽
2023-03-14

我必须这么做

currentSessionFactory = sessionFactory;
sessionFactory.getStatistics().isStatisticsEnabled();

try {
    sessionFactory.getCache().evictQueryRegions();
    sessionFactory.getCache().evictDefaultQueryRegion();
} catch (Exception e) {
}

并重新加载我的实体。很好。

我的实体也在hibernate.xml中

<class-cache usage="read-write" class="entity.Platform" />
杜俊楚
2023-03-14

您需要获取cacheManager,然后获取所有缓存并删除它们。

下面的代码示例将告诉您如何实现这一点:

EhCacheCacheManager cacheManager;   // injected cacheManger

String[] names = cacheManager.getCacheNames();

for (String name : names)
{
    Cache cache = cacheManager.getCache(name);

    cache.removeAll();
}
 类似资料:
  • 在服务器迁移过程中,一个新的nginx配置缺少缓存控制指令。因此,我们最终得到了缓存的,这对我们的SPA非常不利,如果我们部署新代码,它将不再刷新。我们需要index.html不被缓存。 这是我们的(不好的)nginx配置,几天来一直在线: 我们修复了我们的配置: 问题 过去几天内访问过我们网页的客户端缓存了一个旧索引。html。我们如何强制他们的浏览器删除缓存的?

  • 问题内容: 我正在使用未从HTTP请求调用的进程中的Django数据库模型。该过程应该每隔几秒钟轮询一次新数据并对其进行一些处理。我有一个循环,它hibernate了几秒钟,然后从数据库中获取所有未处理的数据。 我看到的是,在第一次获取之后,该进程再也看不到任何新数据。我进行了一些测试,尽管每次我都在构建新的QuerySet,但看起来Django正在缓存结果。为了验证这一点,我从Python sh

  • 问题内容: 因为我以前使用过jQuery的AjAX方法,所以我对XMLHttpRequests较新。但是,我需要在网络工作者中工作,现在我必须使用经典的XMLHttpRequest来解决性能问题。 我正在尝试从jquery 重建-property。如果应该禁用缓存,请添加以下内容: 但是,如果我想强制缓存(不是阻止),应该设置哪个标头? 问题答案: 您可以设置各种标头来鼓励缓存,但是它们(包括您使

  • 问题内容: 我注意到一些浏览器(特别是Firefox和Opera)非常热衷于使用.css和.js文件的缓存副本,即使在浏览器会话之间也是如此。当你更新这些文件之一但用户的浏览器继续使用缓存的副本时,这会导致出现问题。 问题是:强制用户浏览器在文件更改后重新加载文件的最优雅方法是什么? 理想情况下,该解决方案不会强制浏览器在每次访问页面时重新加载文件。我将发布自己的解决方案作为答案,但我很好奇是否有

  • 问题内容: 我有一个页面正在从第三方(新闻提要)加载脚本。脚本的url在加载时动态分配(根据第三方代码)。 然后从中加载的脚本创建并加载具有新闻提要中各种内容的元素,并以漂亮的格式等将元素加载到其中(传入ID“ div1287”,以便脚本知道在何处加载内容)。 唯一的问题是,它只会加载一次。我希望它每n秒重新加载一次(从而显示新内容)。 所以,我想我会尝试一下: div清除后,我得到警报,但是没有

  • 问题内容: 我想确保通过AJAX调用请求的数据是新鲜的,而不是被缓存的。为此,我发送标题 但是如果用户按下F5键,我的Chrome版本33会覆盖此标头。 例。将内容与您的网络服务器放在一起 在网络标签上的Chrome调试器中,我看到了test.html AJAX调用。状态代码200。现在按F5重新加载页面。最长寿命:0,状态码304未修改。 Firefox表现出类似的行为。只是覆盖了请求标头,它会