禁用 JPA 二级缓存不起作用

Posted

技术标签:

【中文标题】禁用 JPA 二级缓存不起作用【英文标题】:Disabling JPA second level cache is not working 【发布时间】:2015-03-28 18:55:39 【问题描述】:

我将 Hibernate JPA 用于我的 Web 应用程序,并将 Apache Tomcat 用于我的 Web 服务器。我的问题是,在更新我的实体 obj 后,我调用另一个函数来获取实体列表。在该实体列表中,我看到的是旧对象而不是更新的对象。

我检查了数据库并且记录已经更新。 但是 EntityManager 正在返回旧对象。

这是我的 persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="2.0" 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">
  <persistence-unit name="Default" transaction-type="RESOURCE_LOCAL">
    <description>
      Persistence unit for the Envers tutorial of the Hibernate Getting Started Guide
    </description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jar-file>D:\Projects\JPATempJars\com.mbc.common.jar</jar-file>
    <jar-file>D:\Projects\JPATempJars\com.mbc.hr.jar</jar-file>
    <shared-cache-mode>NONE</shared-cache-mode>
    <properties>
      <property name="datanucleus.storeManagerType" value="true" />
      <property name="hibernate.bytecode.use_reflection_optimizer" value="true" />
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
      <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/hr" />
      <property name="hibernate.connection.username" value="root" />
      <property name="hibernate.connection.password" value="123123" />
    </properties>
  </persistence-unit>
</persistence>

这是我将对象更新到数据库的简单代码...

public void updateObj(Customer obj) throws Exception 
  EntityManager em = getEntityManager();
  try 
    em.getTransaction().begin();
    entityManager.merge(obj);
    commitTransaction();
   catch (Exception e) 
    em.getTransaction().rollback();
    throw e;
   finally 
    em.close();
  

以下是从数据库中获取对象列表的函数...

public ObjDataList getObjList(CriteriaParams cri) throws Exception 
  EntityManager em = getEntityManager();
  try 
    String l_cri = " where c.column1 like '%" + cri.getKeyword() + "%' or c.column2 like '%" + cri.getKeyword() + "%'";
    String l_searchJPQL = "select c from Customer c" + l_cri;
    List < Customer > l_entityList = em.createQuery(l_searchJPQL, Role.class)
      .setFirstResult(cri.getIndex())
      .setMaxResults(cri.getSize())
      .getResultList();

    ObjDataList l_dataList = new ObjDataList();
    l_dataList.setEntityList(l_entityList);

    if (cri.getIndex() == 0) 
      String l_countQuery = "select count(c.column1) from Customer c" + l_cri;
      l_dataList.setTotalRecord(em.createQuery(l_countQuery, Long.class).getSingleResult());
    

    return l_dataList;
   catch (Exception e) 
    throw e;
   finally 
    em.close();
  

谢谢

【问题讨论】:

更多关于commitTransaction()getEntityManager()如何实现的细节将有助于更好地理解。 --getEntityManager entityManager = emFactory.crearteEntityManager(); --commitTransaction() entityManager.getTransaction().commit(); 【参考方案1】:

如果要绕过缓存从数据库中读取,可以设置缓存模式为刷新。​​

Refresh 还将使用其新发现更新缓存。

请看这里: http://docs.oracle.com/javaee/6/tutorial/doc/gkjjj.html

【讨论】:

【参考方案2】:

这听起来更像是一级缓存的效果。检查创建列表的部分是否确实获得了新的 EntityManager,并且没有重用旧的,其中包括(陈旧的)一级缓存。

【讨论】:

以上是关于禁用 JPA 二级缓存不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 二级缓存疑难点

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

JPA学习(JPA_二级缓存)

Spring Data Jpa缓存介绍

课时11:禁用清理二级缓存,以及整合Ehcache缓存

带有 Hibernate 和 Ehcache 的 Spring 数据 JPA 不起作用