Создать Entitymanager с расширенным контекстом персистентности через CDI

Мы пытаемся создать систему, которая "производит" управляющий объектами в зависимости от пользователя, вошедшего в систему (вид многопользовательского режима). Для этого мы реализовали 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 ответ

Я думаю, вам нужно это: Создайте две фабрики здесь:

@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;
    }
    }

Используйте фабрики для создания EntityManager

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;

Конечно, вы можете использовать спецификатор для различия между фабриками вместо проверки названия поля. Я просто хотел получить больше глубины в ответ.

Другие вопросы по тегам