【问题标题】:JPA cache not invalidatedJPA 缓存未失效
【发布时间】:2014-08-03 18:53:01
【问题描述】:

我正在使用 Eclipse IDE、EclipseLink、JPA 和 MySQL 开发应用程序。在应用程序的初始启动期间,我需要删除表格的内容。但是,删除应用程序后,建立新连接后,仍会从空表中读取旧数据。 我最初的方法是在每次执行操作时创建一个new EntityManager

    private EntityManager entityManager;

    public FacadeFactory() {
        entityManager = DBConnection.connect();
    }

禁用JPA缓存后,问题解决了。

由于性能问题,EntityManager 已更改为 Singleton,以便仅打开一个与数据库的连接。

    private static FacadeFactory instance;
    private EntityManager entityManager;

    private FacadeFactory() {
        entityManager = DBConnection.connect();
    }

    public static FacadeFactory getInstance(){
        if(instance == null){
            instance = new FacadeFactory();
        }
        return instance;
    }

现在,即使缓存仍然被禁用,我也遇到了与以前相同的问题。我试图从 persistence.xml 和代码中禁用缓存,但它们都不适合我。

<property name="eclipselink.cache.shared.default" value="false"/>
entityManager.getEntityManagerFactory().getCache().evictAll();

谁能帮帮我?

【问题讨论】:

  • 在需要时使用新的 EntityManager 有哪些性能问题?它们应该是轻量级的,我能看到的唯一主要好处应该是添加的缓存,无论如何你都希望禁用它。
  • @Chris,我注意到程序在每次创建新的 EntityManager 时运行速度稍慢。

标签: java mysql caching jpa eclipselink


【解决方案1】:

entityManager.getEntityManagerFactory().getCache().evictAll();正在清除共享缓存,而 eclipselink.cache.shared.default" value="false" 也会影响共享缓存。共享缓存也称为二级缓存 - 一级缓存是 EntityManager 本身用于跟踪的缓存托管实体。因为您对所有内容都使用单个 EntityManager,所以所有内容都放在第一级缓存中。

您可以根据需要创建一个新的 EntityManager,也可以偶尔调用 em.clear() 来清除 EntityManager 中的缓存 - 分离您的实体。

【讨论】:

  • 谢谢@Chris!我每次调用 find() 或 findAll() 时都调用 em.refresh(entity) 解决了这个问题。您认为哪一个(刷新或清晰)更好?
  • 我会改为划分您的 EntityManager 以便您可以偶尔调用 clear 来释放资源。对每个查找或查询调用 clear 或 refresh 可能会导致性能问题,但这完全取决于您使用应用程序的方式。
猜你喜欢
  • 2016-09-21
  • 1970-01-01
  • 2018-12-28
  • 2015-04-29
  • 1970-01-01
  • 2015-07-21
  • 2017-09-08
  • 2017-12-20
  • 1970-01-01
相关资源
最近更新 更多