2011-06-08 14 views
8

Tytuł oczywiście stwierdza: Nie mogę sprawić, aby pamięć podręczna drugiego poziomu działała dla JPA2/Hibernate 3.6.3.Przykład pracy z Hibernate 3.6.2 Cache drugiego poziomu z JPA2?

Próbowałem wielu hack, aby to działało. Ale udało mi się tylko uruchomić pamięć podręczną zapytań. Chociaż Hibernuj tworzy pamięć podręczną (nazwę instancji), są one ignorowane. Nawet pomyłki nie są rejestrowane. Może to niezgodność wersji. Próbowałem innych bez rezultatu. I już nie czuję się na siłach, aby wypróbować wszystkie permutacje. :-P

Zadaję tu pytanie, ponieważ niektórzy ludzie wydają się działać (których przykłady próbowałem również). Może dostrzegą oczywisty błąd, który popełniam.

Z góry dziękuję wszystkim, którzy mi pomagają! :-)

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

setup
<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

W ten sposób mogę sprawdzić użycie pamięci podręcznych. Bufory są tworzone (po jednym dla każdej jednostki) i znajdują się tam również dwie pamięci podręczne zapytań. Te ostatnie zapełniają się dość szybko. Ale żadna z pamięci podręcznych nie wykazuje żadnych błędów ani trafień. Nawet pamięć podręczna zapytań.

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

Pamięć podręczna encji jest ignorowana. Powinny zawierać co najmniej jednostki, które są zapisywane w bazie danych. Lub pobierane z zapytaniami. Nic się tam nie porusza.

próbka kodu 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(); 

Przejęcie działa - bo nie ma danych do bazy danych. A znalezisko działa, ponieważ otrzymuję obiekty z wygenerowanymi identyfikatorami.

Ankietowane jednostki są indeksowane w bazie danych.

WHODUNNIT?

+1

Czy rzeczywiście oznaczyłeś swoje podmioty jako @Cacheable? –

+0

Tak. I odpowiednie wyskakujące okienka podręczne w JMX. Tylko encje nie są buforowane podczas kwerendy. Nie w przypadku uporczywości/łączenia. –

Odpowiedz

4

znaleziono sprawcę - chociaż jest to dość intuicyjne:

zapytaliśmy podmioty nie są wprowadzane do pamięci podręcznej drugiego poziomu, chyba że zamknąć menedżera sesji/podmiotu. Nawet jeśli otrzymasz żądanie z tymi samymi obiektami, nadal nie będzie buforowania.

Mam długi proces wsadowy, w którym wiele obiektów referencyjnych jest tworzonych i ponownie wykorzystywanych. Jeśli cały czas utrzymuję tego samego menedżera podmiotu, nie widzę końca procesu. Jeśli odtworzę menedżera encji w każdym cyklu, aplikacja leci.

Myślałem, że było coś takiego jak cache pierwszego poziomu - kontekst utrwalania?

4

Jeden z moich projektów wykorzystuje ehcache + hibernate + jpa2. Mówię ci moją konfigurację. Mam nadzieję, że ci to pomoże.

ramowe wersje (zależnościami 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> 

Obie wersje hibernacji są testowane, ale nie korzystają z API Hibernate jpa2.

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> 

Wreszcie należy opisywania cachable klasę encji. Oto przykład:

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

Ta konfiguracja działa dla mnie, mam nadzieję, że była przydatna.

+0

Dziękujemy! Spróbuję z tym jak najszybciej. W międzyczasie jedyną zauważalną różnicą, jaką widzę, jest to, że jednostka jest Serializowalna. Czy to jest teraz wymagane? –

+0

Myślę, że tutaj możesz znaleźć odpowiedź. http://stackoverflow.com/questions/2020904/when-and-why-jpa-entities-should-implement-serializable-interface – lepike

+0

Podany przykład działa tutaj, ale encje nie są buforowane, gdy są trwałe. Tylko w przypadku pytań. Czy to sposób, w jaki ma działać? –

Powiązane problemy