使用JPA2进行Hibernate 3.6.2二级缓存的工作示例?

Jan*_*rts 8 hibernate ehcache second-level-cache jpa-2.0

标题显然表明它:我无法使二级缓存适用于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>
Run Code Online (Sandbox Code Playgroud)

的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>
Run Code Online (Sandbox Code Playgroud)

JMX设置

这样我就可以检查缓存的用法.创建缓存(每个实体一个),两个查询缓存也在那里.后者填补速度非常快.但是没有一个缓存显示任何未命中或命中.甚至不是查询缓存.

 ManagementService.registerMBeans( CacheManager.getInstance(), ManagementFactory.getPlatformMBeanServer(), true, true, true, true, true )
Run Code Online (Sandbox Code Playgroud)

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

示例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();
Run Code Online (Sandbox Code Playgroud)

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

查询的实体在数据库上编制索引.

WHODUNNIT?

Jan*_*rts 4

找到了罪魁祸首 - 尽管它非常违反直觉:

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

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

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