当前位置: 首页 > 知识库问答 >
问题:

在同一事务中的不同EJB中使用不同的实体管理器

丌官承
2023-03-14
Employee employee = entityManager.find(Employee.class, 1L);

if (employee == null) {
    throw new EntityNotFoundException();
}

由于EntityManager#find()在所述实体不可用的情况下返回null,因此需要进行如上所示的条件测试,以避免可能的java。lang.NullPointerException,否则很可能发生。在任何地方重复这个琐碎的条件测试都是非常不可接受和不鼓励的,这使得业务逻辑应该尽可能简单,几乎不可读。

为了防止这种条件检查到处重复,我在一个单独的EJB中有一个通用方法,

@Stateless
public class EntityManagerUtils implements EntityManagerService {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public <T extends Object> T find(Class<T> entityClass, Object primaryKey) {
        T entity = entityManager.find(entityClass, primaryKey);

        if (entity == null) {
            throw new EntityNotFoundException();
        }

        return entity;
    }
}

从另一个EJB内部调用此方法,如下所示,

@Stateless
public class TestBean implements TestBeanService {

    @PersistenceContext
    private EntityManager entityManager;

    @Inject
    private EntityManagerService entityManagerService;

    @Override
    public void test(Employee employee) {
        Department managedDepartment = entityManagerService.find(Department.class, employee.getDepartment().getDepartmentId());
        System.out.println("contains : " + entityManager.contains(managedDepartment));
    }
}

在这里,尽管所有事情都发生在同一个事务中,entityManager。包含(managedDepartment)返回true,即返回的部门实体由两个EJB中的实体管理器管理。

虽然是意料之中的,但是entityManager.contains(Management edOffice)如何返回true?

使用相同的EntityManager工厂的是同一个EntityManager实例吗?


共有1个答案

有权
2023-03-14

我怀疑EJB规范是否保证EntityManagerJava实例是相同的,但它保证它们由相同的持久性上下文(相同的托管实体集)支持,因为您在同一个JTA事务中,而且两个EntityManager都是由相同的持久性单元(在您的情况下是默认的)进行容器管理的。

如果要检查环境中的实例是否相同,请检查

System.out.println("EntityManager : " + entityManager);

但是我不会依赖它作为您的应用程序服务器的未来版本的保证。

如果您想要一个新的持久性上下文,可以开始一个新事务,或者从注入的EntityManager工厂手动创建一个EntityManager实例。

出于性能考虑,我不想在您的情况下使用新的持久性上下文。

编辑:添加JavaEE7官方教程中的一句话,解释/证明刚才所说的话

持久性上下文将与当前JTA事务一起自动传播,映射到同一持久性单元的EntityManager引用将提供对该事务中持久性上下文的访问。通过自动传播持久性上下文,应用程序组件不需要为了在单个事务中进行更改而相互传递对EntityManager实例的引用。JavaEE容器管理容器管理的实体管理器的生命周期。

 类似资料:
  • 我试图用不同的事务管理器嵌套事务,其中如果嵌套的事务失败,外部主事务也需要回滚 我的spring配置文件有 但是,当失败时,中的事务不会回滚。如何使回滚工作?

  • 我有一个拓扑,其中我有2个不同的源主题(2个子拓扑)。其中一个是Avro格式,另一个是JSON格式。有没有办法为不同的处理器使用不同的SERDE?我已经看到商店里有消费。使用()但我看不到处理器有这样的功能。 除了编写自己的序列化程序或反序列化程序来区分主题和相应的序列化/反序列化之外,是否有使用不同Serde的配置?

  • 我正在JDeveloper 11.1.1.4中开发一个JAX-WS Web服务,它应该使用以前部署到WebLogic服务器的JAR中的EJB。WebService项目和EJB项目都是我自己的代码,但我想分别部署它们。现在我正在试验这种设置。 在Examplejb项目中,我有一个实现远程接口示例的bean ExampleBean。 在该项目中,我有两个部署描述符(ejb-jar.xml和weblog

  • 问题内容: 有一个令人毛骨悚然的项目,其中包含多个spider。我有什么方法可以定义为哪个spider使用哪个管道?并非我定义的所有管道都适用于每个spider。 问题答案: 在Pablo Hoffman的解决方案的基础上,你可以在对象的方法上使用以下装饰器,以便它检查你的Spider属性是否应执行。例如: 为了使此装饰器正常工作,蜘蛛程序必须具有管道属性,其中包含要用于处理项目的管道对象的容器,

  • 我在阅读oracle的多线程官方教程时,遇到了这个例子(假设< code>c1和< code>c2从未一起使用): 据说通过使用锁1 然而,我并不认为这有助于减少阻塞,因为它们彼此之间没有依赖关系。我有多个线程同时运行这两个方法,当我使用lock对象和this关键字时,性能非常相似。 有人可以帮助解释我的困惑吗?喜欢用一个例子来说明差异。 除了这里的讨论,这篇文章也帮助澄清了我的疑虑。要点:将sy

  • 对于登录页面自动化,用户需要输入用户id、安全答案和密码。不同的环境有不同的用户。例如,qa和dev环境的用户具有不同的用户id、安全答案和密码。那么在自动化测试中如何妥善处理用户信息呢?我们可以将所有的属性存储在属性文件中,还有其他更好的解决方案吗?