WildFly 中的 JPA 共享缓存/二级缓存

Posted

技术标签:

【中文标题】WildFly 中的 JPA 共享缓存/二级缓存【英文标题】:JPA shared cache / second level cache in WildFly 【发布时间】:2015-03-19 21:28:03 【问题描述】:

我使用的是 WildFly 8.1、JPA 2.1 和 Hibernate 4.3.5

我想在 WildFly 中使用 JPA 共享缓存/二级缓存

我遵循 WildFly 文档:https://docs.jboss.org/author/display/WFLY8/JPA+Reference+Guide#JPAReferenceGuide-UsingtheInfinispansecondlevelcache

这是我的 persitience.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="myAppPU" transaction-type="JTA">
    <jta-data-source>java:/jdbc/myAppDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="org.hibernate.flushMode" value="MANUAL"/>
      <property name="hibernate.cache.use_second_level_cache" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

我将属性 hibernate.cache.use_second_level_cache 设置为 true 并将共享缓存模式设置为 ENABLE_SELECTIVE

我要缓存的实体(@Entity)用@Cacheable(true)注解,像这样:

@Entity
@Cacheable(true)
public class Tooltip implements Serializable 
  @Id
  private String path ;
  private String description ;
  private Boolean rendered ;
  //...

但是每次我访问一个网页时,hibernate 都会生成很多选择来获取我指示为@Cacheable(true) 的所有实体,即使我已经访问了该页面(在同一个会话中)。

所以看来共享缓存/二级缓存不起作用

我错过了什么吗?


谢谢赫尔曼

我尝试在 persitence.xml 中将 hibernate.cache.use_query_cache 设置为 true

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="myAppPU" transaction-type="JTA">
    <jta-data-source>java:/jdbc/myAppDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="hibernate.cache.use_second_level_cache" value="true"/>
      <property name="hibernate.cache.use_query_cache" value="true" />
      <property name="org.hibernate.flushMode" value="MANUAL"/>
    </properties>
  </persistence-unit>
</persistence>

以及我正在使用的查询中的提示

@Entity
@NamedQueries(
    @NamedQuery(name = "FieldInfos.findAll", query = "SELECT i FROM FieldInfos i", hints = @QueryHint(name="org.hibernate.cacheable",value="true")),
    @NamedQuery(name = "FieldInfos.findByPath", query = "SELECT i FROM FieldInfos i WHERE i.path = :path", hints = @QueryHint(name="org.hibernate.cacheable",value="true"))
)
@Cacheable(true)
public class FieldInfos implements Serializable 
    //...

问题依然存在

我也尝试使用新版本的 WildFly:8.2 所以 Hibernate 4.3.7 但问题仍然存在

【问题讨论】:

你的问题解决了吗? 您是否启用了统计并检查了 WildFly 管理控制台 > 运行时 > JPA 选项卡? 【参考方案1】:

二级缓存只影响直接实体查找,对应EntityManager.find()

如果您想避免各种SELECT 查询影响您的缓存实体,您还需要启用查询缓存:

    <property name="hibernate.cache.use_query_cache" value="true" />

您需要为每个要缓存的查询设置查询提示org.hibernate.cacheable=true

【讨论】:

谢谢你,但不幸的是它对我不起作用,我编辑我的帖子来解释 在查询中设置可缓存很重要,也许你可以显示客户端代码看看你做对了吗?或者,为org.hibernate 甚至org.infinispan 启用 TRACE 日志记录以查看到底发生了什么。使用远程调试器单步调试代码也会有所帮助。

以上是关于WildFly 中的 JPA 共享缓存/二级缓存的主要内容,如果未能解决你的问题,请参考以下文章

JPA学习(JPA_二级缓存)

JPA学习笔记(11)——使用二级缓存

禁用 JPA 二级缓存不起作用

16-二级缓存

MyBatis之二级缓存

在hibernate中配置共享缓存模式