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

时间:2015-08-05 18:37:09

标签: hibernate jpa ejb eclipselink entitymanager

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.contains(managedDepartment)返回true,即返回的Department实体由两个EntityManager实体管理。 EJBs。

虽然可以预期,entityManager.contains(managedDepartment)如何返回true?

是否使用相同的EntityManager

是同一个EntityManagerFactory实例

1 个答案:

答案 0 :(得分:4)

我怀疑EJB规范保证EntityManager Java实例是相同的,但它保证它们由相同的Persistence Context(同一组托管实体)支持,因为你在相同的JTA事务,因为EntityManagers都是同一个持久性单元的容器管理(在您的情况下是默认值)。

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

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

但我不会依赖它作为未来版本的Application Server的保证。

如果您想要新的持久性上下文,您可以开始新的事务,也可以从注入的EntityManager手动创建EntityManagerFactory实例。

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

修改:添加official JavaEE 7 Tutorial的引文,解释/证明其所说的内容

  

持久性上下文随当前一起自动传播   JTA事务以及映射到的 EntityManager引用   相同的持久性单元提供对内部持久性上下文的访问   该交易。通过自动传播持久性   上下文,应用程序组件不需要传递引用   EntityManager个实例,以便在其中进行更改   单笔交易。 Java EE容器管理生命周期   容器管理的实体经理。