Java JPA实体未刷新(对每个事务使用新的EntityManger)

Java JPA实体未刷新(对每个事务使用新的EntityManger),java,jakarta-ee,jpa,persistence,Java,Jakarta Ee,Jpa,Persistence,我对JPA将旧数据保留在缓存中有问题,并且尝试了我能找到的解决方案,但它总是出现 无论如何,为了提高效率,我最初重用了一个实体管理器实例。当我第一次遇到描述的问题时,我更改了代码,以便为每个事务创建一个新的实体管理器: /** This method is called every time a transaction is made. */ public static EntityManager createFreshEntityManager() { try { r

我对JPA将旧数据保留在缓存中有问题,并且尝试了我能找到的解决方案,但它总是出现

无论如何,为了提高效率,我最初重用了一个实体管理器实例。当我第一次遇到描述的问题时,我更改了代码,以便为每个事务创建一个新的实体管理器:

/** This method is called every time a transaction is made. */

public static EntityManager createFreshEntityManager() {
    try {
        return Persistence.createEntityManagerFactory(puName)
                          .createEntityManager();         
    } 
    catch (Exception e) {
        logStuff(e); 
        return null;
    }
}
然而,这并不能解决问题

当我使用JDBC截断一个表并重置主键时,我经常注意到某些新创建的对象有旧的变量值。我的一个怀疑是重置主键可能是一个罪魁祸首,但再一次,我已经在每个事务中有了一个新的实体管理器,所以这一点都不重要

我很有信心,这不是我的代码的问题,因为DB实体永远不会存储在我的应用程序的函数范围之外,并且总是在需要时直接从DB查询

我也读过关于使用EntityManager.clear()的文章,但我不想做那么残忍的事情,因为它会搞乱多线程程序


我曾想过使用JPA而不是JDBC进行截断,一次获取所有对象,然后手动逐个删除它们,但这样做效率很低。。。但话说回来,这并不是一个瓶颈。不确定这是否会产生影响。不过,w.r.t.使用JDBC进行操作。

我不认为有任何理由为每个事务创建一个新的EntityManager

您应该能够使用注入

它可能看起来像这样:

@Stateless
class SomeSessionBean implements SomeSessionBeanLocal {

    @PersistenceContext(unitName = "somePuName")
    private EntityManager em;

    public Customer findCustomerById(Long someId) {
        return em.find(Customer.class, someId);
    }
}
使用注释进行依赖注入是EJB3最伟大的事情之一


问题的可能来源:

如果在javaeeweb应用程序运行时修改数据库中的值,那么ejb可能不会立即检测到这些更改。您的peristence层可能正在使用缓存


您可能希望在“从外部”更改数据库后重新启动Web应用程序。

创建实体管理器并不昂贵,但创建实体管理器工厂是一个昂贵的过程。你应该只创建一次工厂。是的,但即使这样也无助于解决我的问题。很有趣!我以前没有使用@PersistenceContext注释。你是说@PersistenceContext(unitName=“一些新手最喜欢的单元名”)删除了createFreshEntityManager()函数的必要性吗?我想我每天都会学到一些新东西。帮自己一个忙,看看依赖注入。这会让你的生活更轻松!要回答您的问题,可以:您只需将PersistenceContext注入EntityManager,并从您的问题中删除所有代码。据我所知,大多数人都是这样做的。我将用一个例子来编辑我的答案……谢谢,“依赖注入”是我今天的关键词。