Создать 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;
Конечно, вы можете использовать спецификатор для различия между фабриками вместо проверки названия поля. Я просто хотел получить больше глубины в ответ.