通过CDI生成具有扩展持久性上下文的Entitymanager

时间:2012-10-17 06:50:46

标签: ejb cdi entitymanager multi-tenant stateful

我们正在尝试构建一个系统,该系统根据登录用户(多租户类型)“生成”实体管理器。因此我们实现了这样的无状态ejb:

@Stateless
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class CustomEntityManagerFactory {

  @PersistenceContext(unitName = "EM1")
  private EntityManager em1;

  @PersistenceContext(unitName = "EM2")
  private EntityManager em2;

  @Produces
  @RequestScoped
  public EntityManager getEntityManager() {
    // check which entitymanager to return
  }
}

实体管理器注入如下:

@Stateless
public class EmployeeService {

  @Inject
  private EntityManager em;

  ...

}

只要不需要扩展持久化上下文的实体管理器(在无状态ejb中),此生成器就可以工作。不幸的是,我们还有一些有状态的ejbs,它们需要扩展的持久化上下文。有没有办法为此目的实现CDI生成器,或者这种方法是否仅适用于具有事务实体管理器的无状态ejb?

1 个答案:

答案 0 :(得分:-1)

我的猜测是你需要这个: 在这里创建两个工厂:

@ApplicationScoped
public class EntityManagerFactoryProducer {

    private static EntityManagerFactory factory;
    private static EntityManagerFactory factory2;

    @Produces
    public EntityManagerFactory getEntityManagerFactory(InjectionPoint ip) {
    // if the field is named exactly factory2 then factory2 is produced
    if (ip.getMember().getName().equals("factory2")) {

        if (factory2 == null) {
        factory2 = Persistence.createEntityManagerFactory("EM2");
        }
        return factory2;
    }

    else {
        if (factory == null) {
        factory = Persistence.createEntityManagerFactory("EM1");
        }
        return factory;
    }
    }

使用工厂创建EntityManagers

public class EntityManagerProducer {
    @Inject
    private EntityManagerFactory factory;

    @Inject
    private EntityManagerFactory factory2;

    @Produces
    @RequestScoped
    public EntityManager getEntityManager() {
        return factory.createEntityManager();
    }

    @Produces
    @RequestScoped
    @MyCustomQualifier
    public EntityManager getEntityManager2() {
        return factory2.createEntityManager();
    }

}

用于实体管理者之间差异的限定符

@Qualifier
@Retention(RUNTIME)
@Target({FIELD })
public @interface MyCustomQualifier {
    @Nonbinding
    public String value() default "";
}

最终用法:

@Inject
EntityManager em;

@Inject
@MyCustomQualifier
EntityManager em2;

当然,您可以使用限定符来区分工厂,而不是检查字段的名称。我只想更深入地了解答案。