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

时间:2012-08-27 16:16:11

标签: java java-ee jpa persistence

我遇到的问题是JPA将旧数据保存在缓存中并尝试了我能找到的解决方案,但它一直在弹出!

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

/** 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截断表并重置主键时,我经常注意到某些新创建的对象具有旧的变量值。我有一个怀疑是重置主键可能是罪魁祸首,但话说回来,我已经为每个事务都有一个新的实体管理器,所以这根本不重要。

我非常有信心这不是我的代码的问题,因为数据库实体永远不会存储在我的应用程序之外的功能范围内,并且在需要时总是直接从数据库中查询。

我也读过有关使用EntityManager.clear()的内容,但我不想做那些残酷的事情,因为它会搞乱多线程程序。

我曾经想过通过一次获取所有对象然后手动删除它们来使用JPA而不是JDBC来进行TRUNCATE,但这只是效率低下......但是再次,它不会成为瓶颈。不确定这是否会对w.r.t产生影响。尽管如此使用JDBC。

1 个答案:

答案 0 :(得分:2)

我认为没有理由为每个事务创建一个新的EntityManager。

您应该可以使用EntityManager注入@PersistenceContext

它可能看起来像这样:

@Stateless
class SomeSessionBean implements SomeSessionBeanLocal {

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

    public Customer findCustomerById(Long someId) {
        return em.find(Customer.class, someId);
    }
}

使用注释进行依赖注入是EJB 3最重要的事情之一!


问题的可能来源:

如果在JavaEE Web应用程序运行时修改数据库中的值,则EJB不可能立即检测到这些更改。你的持久层可能正在使用缓存。

您可能希望在进行数据库更改“external ”后重新启动您的webapp。