Рабочий пример Hibernate 3.6.2 2-го уровня кеширования с JPA2? - PullRequest
8 голосов
/ 08 июня 2011

В заголовке, очевидно, говорится: я не могу заставить работать кэш второго уровня для 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();

Слияние работает - потому что в базу данных есть данные.И поиск работает, потому что я получаю объекты с сгенерированными идентификаторами.

Запрошенные объекты индексируются в базе данных.

WHODUNNIT?

Ответы [ 2 ]

4 голосов
/ 16 июня 2011

Обнаружил виновника - хотя это довольно нелогично:

Запрашиваемые сущности не помещаются в кэш второго уровня, пока вы не закроете менеджер сеансов / сущностей.Даже если вы запрашиваете те же самые объекты, кэширование по-прежнему не происходит.

У меня есть длительный пакетный процесс, в котором многие ссылочные объекты создаются и используются повторно.Если я все время держу один и тот же менеджер сущностей, я не вижу конца процесса.Если я воссоздаю менеджер сущностей в каждом цикле, приложение вылетает.

Я думал, что есть что-то вроде кэша 1-го уровня - контекст постоянства?

4 голосов
/ 09 июня 2011

Один из моих проектов использует 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 {
}

Эта конфигурация работает для меня, надеюсь, она была полезна.

...