【问题标题】:Working example of Hibernate 3.6.2 2nd level caching with JPA2?使用 JPA2 的 Hibernate 3.6.2 二级缓存的工作示例?
【发布时间】:2011-09-11 01:31:13
【问题描述】:

标题很明显:我不能让二级缓存为 JPA2/Hibernate 3.6.3 工作。

我一直在尝试许多技巧以使其正常工作。但我只是成功地让查询缓存工作。尽管 Hibernate 创建了缓存(实例的名称),但它们被忽略了。即使错过了也不会被登记。可能是版本不兼容。我尝试了其他一些没有结果。而且我不再愿意尝试所有排列。 :-P

我在这里问这个问题,因为有些人似乎可以正常工作(我也尝试过他们的例子)。也许他们能发现我犯的明显错误。

提前感谢任何帮助我的人! :-)

persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
         version="2.0">

<persistence-unit name="foo" transaction-type="RESOURCE_LOCAL">
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:derby:/opt/db/foo;create=true"/>
        <property name="javax.persistence.jdbc.user" value="foo"/>
        <property name="javax.persistence.jdbc.password" value="bar"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>
        <property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
        <property name="hibernate.cache.use_second_level_cache" value="true"/>
        <property name="hibernate.cache.use_query_cache" value="true"/>
    </properties>
</persistence-unit>

pom.xml

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.6.3.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache-core</artifactId>
    <version>2.4.2</version>

JMX 设置

这样我可以检查缓存的使用情况。创建缓存(每个实体一个),并且两个查询缓存也在那里。后者的填充速度非常快。但是没有一个缓存显示任何未命中或命中。甚至查询缓存都没有。

 ManagementService.registerMBeans( CacheManager.getInstance(), ManagementFactory.getPlatformMBeanServer(), true, true, true, true, true )

实体缓存被忽略。它们至少应包含保存到数据库中的实体。或通过查询检索。那里什么都没有。

Java 代码示例

EntityManager entityManager = Persistence.createEntityManagerFactory("foo").createEntityManager();
entityManager.getTransaction.begin();
entityManager.merge(bar);
entityManager.getTransaction.commit();   

Query query = entityManager.createQuery("select b from Bar p where b.name = :name");
query.setParameter("name", "fooBar");
query.setHint("org.hibernate.cacheable","true");
query.getSingleResult();

合并有效 - 因为数据库中有数据。并且查找有效,因为我正在获取具有生成 id 的对象。

查询的实体在数据库中被索引。

谁知道?

【问题讨论】:

  • 您是否将实体标记为@Cacheable?
  • 是的。并在 JMX 中弹出正确的缓存。只有实体在查询时不会被缓存。不是在持久化/合并时。

标签: hibernate jpa-2.0 ehcache second-level-cache


【解决方案1】:

我的一个项目使用 ehcache + hibernate + jpa2。我告诉你我的配置。希望对你有帮助。

框架版本(maven依赖):

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <!-- <version>3.6.2.Final</version> -->
    <version>4.0.0.Alpha1</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <!-- <version>3.6.2.Final</version> -->
    <version>4.0.0.Alpha1</version>
</dependency>
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.0.0</version>
</dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache-core</artifactId>
        <version>2.3.1</version>
    </dependency>

两个hibernate版本都测试过了,但是我没有使用hibernate jpa2 api。

persistence.xml:

<persistence-unit name="UNIT" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>java:/comp/env/ds</non-jta-data-source>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="false" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>

        <!-- 2nd level cache -->
        <property name="hibernate.cache.provider_class"
            value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
        <property name="net.sf.ehcache.configurationResourceName"
            value="/ehcache.xml" />
        <property name="hibernate.cache.use_query_cache" value="true" />
        <property name="hibernate.cache.use_second_level_cache"
            value="true" />
        <property name="hibernate.generate_statistics" value="false" />
    </properties>
</persistence-unit>

ehcache.xml:

<ehcache updateCheck="false">

    <diskStore path="java.io.tmpdir" />

    <defaultCache maxElementsInMemory="10000" eternal="false"
        statistics="true" timeToIdleSeconds="120" timeToLiveSeconds="120"
        overflowToDisk="true" diskPersistent="false" 
        diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />

    <cache name="com.yourcompany.CachedEntity" eternal="true"
        maxElementsInMemory="1000" />                       
</ehcache>

最后你应该注释你的可缓存实体类。这是一个例子:

package com.yourcompany;
@Entity
@Table(name="cached_entity")
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class CachedEntity implements Serializable {
}

这个配置对我有用,希望有用。

【讨论】:

  • 谢谢!我会尽快尝试一下。同时,我看到的唯一明显区别是实体是可序列化的。现在有这个要求吗?
  • 我想在这里你可以找到答案。 stackoverflow.com/questions/2020904/…
  • 此处提供的示例有效,但实体在持久化时不会被缓存。只有在被查询时。这就是它的工作方式吗?
  • 我认为这仅意味着查询缓存。我不知道您如何缓存实体以进行持久化。如果你使用 batchinsert 或 batchupdate,jdbc 驱动会为你管理这种缓存。
【解决方案2】:

找到了罪魁祸首——虽然这很违反直觉:

除非您关闭会话/实体管理器,否则查询的实体不会被放入二级缓存。即使您使用完全相同的对象重新查询,仍然不会发生缓存。

我有一个很长的批处理过程,其中创建和重用了许多参考对象。如果我一直使用同一个实体管理器,我看不到流程的结束。如果我在每个周期重新创建实体管理器,应用程序就会运行。

我认为有类似一级缓存的东西 - 持久性上下文?

【讨论】:

    猜你喜欢
    • 2015-10-13
    • 1970-01-01
    • 2010-10-16
    • 2015-05-14
    • 2020-11-20
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2010-11-16
    相关资源
    最近更新 更多