使用 JBoss Hibernate 缓存缓存 EJB 实体 (JBoss-5.0.0.GA)

发布于 2024-11-09 03:59:45 字数 3408 浏览 0 评论 0原文

我的应用程序经常查询数据库以获取很少更改的数据。因此,我决定使用缓存的 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:缓存未处于启动状态! 在 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) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597)

我应该做一些额外的设置吗? 任何帮助表示赞赏!

提前致谢, 皮奥特尔

My applications very often queries database for rarely-changed data. So I've decided to optimize it using cached EJB entities as desribed in:
http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Caching_EJB3_Entities.html

However, when I take a look at hibernate sql logs (hibernate.show_sql = true) I can still see the same number of queries hitting database as without cache configured. Here is my persistence.xml file:

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

All my JPA entities are annotated with:

@Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)

Maybe a little hint will be that when I shut down server the following exception can be seen in logs:

org.hibernate.cache.CacheException: java.lang.IllegalStateException: Cache not in STARTED state!
at org.hibernate.cache.jbc2.BasicRegionAdapter.destroy(BasicRegionAdapter.java:243)
at org.hibernate.impl.SessionFactoryImpl.close(SessionFactoryImpl.java:813)
at org.hibernate.ejb.EntityManagerFactoryImpl.close(EntityManagerFactoryImpl.java:46)
at org.jboss.jpa.deployment.ManagedEntityManagerFactory.destroy(ManagedEntityManagerFactory.java:93)
at org.jboss.jpa.deployment.PersistenceUnitDeployment.stop(PersistenceUnitDeployment.java:343)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
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)

Should I do some additional setup?
Any help is appreciated!

Thanks in advance,
Piotr

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瞄了个咪的 2024-11-16 03:59:45

缓存查询(正如 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 {
}

我不知道这是否是一般规则,但就我而言,在添加这些之后注释,一切开始按预期工作。

Caching queries (as skaffman suggested):

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

In case of entities, I noticed, that it not enough to annotate all entities with @Cache. If your entity has reference to other entities (annotated with @Cache), you must also include this annotation on a top of a referencing field:

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

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

I don't know if it's general rule, but in my case, after I've added these annotations, everything started to work as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文