标题显然表明:我无法使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的对象。
查询的实体在数据库上建立索引。
WHODUNNIT?
找到了罪魁祸首-尽管这很违反直觉:
除非关闭会话/实体管理器,否则查询的实体不会放入二级缓存中。即使您使用完全相同的对象重新查询,仍然不会进行缓存。
我有一个漫长的批处理过程,在其中创建和重用了许多参考对象。如果我一直保持相同的实体管理器,则看不到流程的结束。如果我在每个周期都重新创建实体管理器,则应用程序运行正常。
我以为有一级缓存-持久性上下文?