【问题标题】:EntityManager properties get lost after transaction finishes?EntityManager 属性在事务完成后丢失?
【发布时间】:2014-09-01 20:01:06
【问题描述】:

我在 Glassfish 4 上运行了一些代码,这些代码在 EntityManager(javax.persistence.EntityManager) 上设置属性,这发生在事务期间。

在另一笔交易中,我想读取属性,但我发现它们已经消失了。

我看到在这两种情况下它都是同一个 EntityManager 对象(实际上它是一个 EntityManagerWrapper):

com.sun.enterprise.container.common.impl.EntityManagerWrapper@5a346e8f

属性是否仅在事务的生命周期内有效?

我通过注入得到EntityManager(实际上注入的对象就是上面提到的包装器):

@PersistenceContext(unitName = IEntityManagerService.DEFAULT_PERSISTENCE_UNIT)
    protected void setManager(final EntityManager manager) {
        assert manager != null;
        this.manager = manager;
    }

【问题讨论】:

  • 你的意思是 em.setProperty ?它们应该在 EntityManager 的整个生命周期内保存; javadocs/spec 中没有任何内容可以说明实现可以在提交任何 txn 后将它们丢弃。也许这个“包装器”是罪魁祸首,而真正的 EntityManager 拥有它们 - 那么为什么不尝试处理真正的 EM 呢?
  • @NeilStockton 是的,em.setProperty。 EM Wrapper 被注入(参见对 OP 的编辑),所以我不确定我是否会通过获取底层 EM 来违反容器规则。

标签: jakarta-ee jpa glassfish jta


【解决方案1】:

这是容器管理 EntityManager 的默认行为。

EntityManager 的实际实例在每个事务中创建和销毁,EntityManagerWrapper 只是一个代理,它将调用委托给与当前事务关联的EntityManager

如果您的EntityManager 被注入到有状态对象中,您可以将其配置为跨越多个事务using type = PersistenceContextType.EXTENDED,但我认为这不是您所需要的。

此外,还不清楚为什么要在事务之间保留EntityManager 属性。 EntityManager.setProperty() 通常用于配置底层 JPA 实现的供应商特定选项,而不是作为事务之间通信的一种方式。

【讨论】:

  • 是否有任何官方文档可以解释这一点? EntityManager 文档中没有提到它。我想保留属性,因为其中一些是当前登录用户的安全角色之类的东西。我不想在每笔交易中都重置它们。
  • 容器管理 EntityManager 的行为在 JPA 规范中进行了描述。 EntityManager 不是保留安全角色的正确位置。我认为 Glassfish 应该有一些特殊的安全基础设施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
相关资源
最近更新 更多