Hibernate 3.6.2的工作示例JPA2的二级缓存? [英] Working example of Hibernate 3.6.2 2nd level caching with JPA2?

查看:150
本文介绍了Hibernate 3.6.2的工作示例JPA2的二级缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题明显表示:我无法让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 =footransaction-type =RESOURCE_LOCAL>
< shared-cache-mode> ENABLE_SELECTIVE< / shared-cache-mode>
<属性>
< property name =javax.persistence.jdbc.drivervalue =org.apache.derby.jdbc.EmbeddedDriver/>
< property name =javax.persistence.jdbc.urlvalue =jdbc:derby:/ opt / db / foo; create = true/>
< property name =javax.persistence.jdbc.uservalue =foo/>
< property name =javax.persistence.jdbc.passwordvalue =bar/>
< property name =hibernate.dialectvalue =org.hibernate.dialect.DerbyDialect/>
< property name =hibernate.hbm2ddl.autovalue =create/>
< property name =hibernate.cache.region.factory_classvalue =net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory/>
< property name =hibernate.cache.use_second_level_cachevalue =true/>
< property name =hibernate.cache.use_query_cachevalue =true/>
< / properties>
< / persistence-unit>



pom.xml

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

JMX设置

这样我可以检查缓存的使用情况。创建缓存(每个实体一个)并且两个查询缓存也在那里。后者正在快速增长。但是没有一个缓存显示任何错过或命中。



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

实体高速缓存被忽略。它们应该至少包含保存到数据库中的实体。或者通过查询进行检索。


$ b

示例Java代码

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

查询查询= entityManager.createQuery(从b栏中选择b,其中b.name =:name);
query.setParameter(name,fooBar);
query.setHint(org.hibernate.cacheable,true);
query.getSingleResult();

合并有效 - 因为有数据存入数据库。查找工程,因为我得到的对象与生成的ID。

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


$ WHODUNNIT

解决方案

b $ b

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



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



我认为这有点像一级缓存 - 持久化上下文吗?


The title obviously states it : I can't make the second-level cache work for JPA2/Hibernate 3.6.3.

I've been trying many a hack to make it work. But I'm only succeeding in having the query cache working. Although Hibernate creates the caches (name of the instance), they're ignored. Even misses are not registered. Maybe it's a version incompatibility. I've tried some others with no result. And I don't feel up to the task anymore to try all permutations. :-P

I'm asking the question here as some people seem to have it working (whose examples I tried also). Maybe they can spot the obvious error I'm making.

Thanks in advance for anybody helping me out ! :-)

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 setup

This way I can check the usage of the caches. The caches are created (one for each entity) and the two query caches are there too. The latter are filling up pretty fast. But none of the caches display any misses or hits. Not even the query caches.

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

The entity caches are ignored. They should contain at least the entities that are saved into the database. Or being retrieved with queries. Nothing moves there.

Sample Java code

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();

The merge works - because there's data into the database. And the find works because I'm getting objects with generated id's.

The queried entities are indexed on the database.

WHODUNNIT ?

解决方案

Found the culprit - although it's pretty counter-intuitive:

Queried entities are not put into the second-level cache unless you close the session/entity manager. Even if you requery with the very same objects, still no caching will happen.

I have a long batch process in which many reference objects are created and reused. If I keep the same entity manager all along, I don't see the end of the process. If I recreate the entity manager at each cycle, the application flies.

I thought there was something like a 1st level cache - the persistence context ?

这篇关于Hibernate 3.6.2的工作示例JPA2的二级缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆