Кэширование сущностей EJB с использованием кеша JBoss Hibernate (JBoss-5.0.0.GA) - PullRequest
2 голосов
/ 22 мая 2011

Мои приложения очень часто запрашивают в базе данных редко изменяемые данные. Поэтому я решил оптимизировать его, используя кэшированные сущности EJB, как описано в: http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Caching_EJB3_Entities.html

Однако, когда я просматриваю журналы hibernate sql (hibernate.show_sql = true), я все равно вижу то же количество запросов, попадающих в базу данных, что и без настроенного кэша. Вот мой файл 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_1_0.xsd"
      version="1.0">


      <persistence-unit name="myds">
         <jta-data-source>java:/myds</jta-data-source>

         (...) classes definitions
         <class>com.my.class.MyEntityOne</class>
         (...)

         <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.format_sql" value="false" />
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
            <property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>


            <!-- 2nd level cache -->                                       
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
            <property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
            <property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
            <property name="hibernate.cache.region.jbc2.cfg.query" value="local-query"/>
         </properties>
      </persistence-unit>

Все мои объекты JPA помечены:

@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)

Возможно, небольшой намек на то, что когда я выключаю сервер, в журналах можно увидеть следующее исключение:

org.hibernate.cache.CacheException: java.lang.IllegalStateException: Кэш не находится в состоянии STARTED! в org.hibernate.cache.jbc2.BasicRegionAdapter.destroy (BasicRegionAdapter.java:243) в org.hibernate.impl.SessionFactoryImpl.close (SessionFactoryImpl.java:813) в org.hibernate.ejb.EntityManagerFactoryImpl.close (EntityManagerFactoryImpl.java:46) в org.jboss.jpa.deployment.ManagedEntityManagerFactory.destroy (ManagedEntityManagerFactory.java:93) в org.jboss.jpa.deployment.PersistenceUnitDeployment.stop (PersistenceUnitDeployment.java:343) at sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke (Method.java:597)

Должен ли я сделать некоторые дополнительные настройки? Любая помощь приветствуется!

Заранее спасибо, Петр

1 Ответ

1 голос
/ 25 мая 2011

Кэширование запросов (как предложил skaffman):

Query query = manager.createQuery("SELECT i FROM ....");
query.setHint("org.hibernate.cacheable", true);

В случае сущностей я заметил, что этого недостаточно, чтобы аннотировать все сущности с помощью @Cache.Если ваша сущность имеет ссылку на другие сущности (помеченные @Cache), вы также должны включить эту аннотацию в верхнюю часть поля ссылки:

@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
public class EntityA {
  @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
  private Set<EntityB> entitiesB;
}

@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
public class EntityB {
}

Я не знаю, является ли это общим правилом, но вВ моем случае, после того, как я добавил эти аннотации, все начало работать как положено.

...