Я пытаюсь выяснить, как это сделать с CDI. Я работаю над приложением, в котором пользователи могут подключаться к нескольким базам данных. Приложение запрашивает, к которому они хотят подключиться, и они также могут отключиться и подключиться к другой базе данных. Это приложение Java SE, использующее Seam для CDI и Hibernate для JPA. Я пытаюсь выяснить, как использовать CDI для подключения @PersistenceContext, а также сделать его динамическим, чтобы к ним можно было обращаться к различным базам данных. Я просто не уверен, что шаблон или техника я бы использовал для этого с CDI. Мысли?CDI вводят @PersistenceContext на основе ввода пользователем
ответ
Так что я думаю, я понял, что я хотел сделать с помощью javax.enterprise.inject.Instance
. Сначала определим простой боб:
@Alternative
public class Foo {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Оно определяется как @Alternative
так КДИ не запутаться между этим и метод производителя (показано ниже). Лучшим решением было бы слишком определить Foo
в качестве интерфейса, тогда FooImpl
будет аннотирован @Typed
, поэтому CDI считает, что это только тип bean-типа FooImpl
. В любом случае, следующий - класс продюсеров.
@ApplicationScoped
public class FooProducer {
private int value;
public FooProducer() {
value = -1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Produces
public Foo getFoo() {
Foo p = new Foo();
p.setValue(getValue());
return p;
}
}
getFoo()
метод создает новый объект Foo
с различными значениями. Значение может быть изменено с помощью метода setValue(int)
. Затем я использую javax.enterprise.inject.Instance
для ввода Foo
.
@Inject
Instance<Foo> fooInstance;
@Inject
FooProducer fooProducer;
....
fooProducer.setValue(10);
Foo foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
fooProducer.setValue(10000);
foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
Здесь я использую впрыскиваемого fooProducer.setValue()
способ изменить то, как производитель будет производить Foo
. Когда fooInstance.get()
называется первый раз Foo
будет содержать значение 10, а второй раз, когда он будет иметь значение 10000.
Учитывая этот простой пример, легко применить к получению EntityManager
экземпляров к различным базам данных во время выполнения. Есть немного больше кода, который производит EntityManager
, но не слишком много.
PersistenceContext обрабатывается контейнером EJB. Поскольку вы не находитесь в контейнере EJB, забудьте о контексте сохранения и рассмотрите возможность использования производителей CDI.
@ApplicationScoped
public class EntityManagerFactoryProvider {
private EntityManagerFactory emf;
public void voidApplicationEMF() {
//load the EMF here based on dynamic properties
this.emf = Persistence.createEntityManagerFactpry(Map of loaded properties);
}
@Produces
public EntityManager em() {
return emf.createEntityManager();
}
}
Тогда где-то в коде
@SessionScoped
public class MyEntityController {
@Inject
private EntityManager emf;
}
Есть еще вопросы, которые имеют дело с операциями и т.д.
В JSE среде, вы должны явно начать и совершить/отката транзакции. Поскольку вы используете CDI, вы можете использовать Interceptors для запуска/проверки состояния транзакции и отката/фиксации по мере необходимости.
@Interceptor
public class MyInterceptor {
@Inject
private EntityManager em;
@AroundInvoke
public Object intercept(InvocationContext ic) {
try {
//initiate transaction
em.getTransaction().start ....
return ic.proceed();
}catch(Exception ex) { //rollback if necessary }
finally {//commit transaction if necessary }
}
}
- 1. Inject PersistenceContext с CDI
- 2. Multilple PersistenceContext CDI
- 3. Сгенерировать HTML-файлы на основе ввода пользователем
- 4. Перенаправление на основе ввода пользователем
- 5. Python: Сохранение файла на основе ввода пользователем
- 6. Итерация стоп-цикла на основе ввода пользователем
- 7. Создание объектов на основе ввода пользователем
- 8. Создание пронумерованных форм на основе ввода пользователем
- 9. SSRS: выполнить запрос на основе ввода пользователем
- 10. Определение типа объекта на основе ввода пользователем
- 11. Создание массивов на основе ввода пользователем
- 12. Изменение атрибутов на основе ввода пользователем
- 13. osCommerce: пользовательская цена на основе ввода пользователем
- 14. Создание нескольких объектов на основе ввода пользователем
- 15. Как выполнить цикл на основе ввода пользователем?
- 16. Как сгенерировать JButton на основе ввода пользователем?
- 17. Удалить элементы XML на основе ввода пользователем
- 18. Именование переменных на основе ввода пользователем (Java)
- 19. добавление строки автоматически на основе ввода пользователем
- 20. открытие файла на основе ввода пользователем C++
- 21. Создать класс на основе ввода пользователем
- 22. Ada инициализирует массив на основе ввода пользователем
- 23. Открыть файл на основе ввода пользователем
- 24. Java-цикл на основе ввода пользователем
- 25. Выбор подкласса на основе ввода пользователем?
- 26. массив на основе ввода пользователем, ошибка?
- 27. Сортировка или Mergesort на основе ввода пользователем
- 28. Возвращаемое значение на основе ввода пользователем
- 29. Как перезапустить программу на основе ввода пользователем?
- 30. Создание текстовых полей на основе ввода пользователем
> 'PersistenceContext обрабатывается контейнером EJB' - это неверно. JPA - отдельная спецификация из EJB, а контекст персистентности обычно задается специфической частью Java EE для реализации JPA. –
@ArjanTijms фактически спецификация JPA является частью спецификации EJB, только выделенный документ разделен – maress
Я не понимаю, как реализовать часть, которую вы комментируете как «// загружаем EMF здесь на основе динамических свойств». Я не хочу класс производителя должен отвечать за пользовательский интерфейс. Я пытаюсь понять путь MVC - представление касается получения динамической информации, а затем передачи ее производителю. Теперь, когда я обдумываю это, пока я печатаю, возможно, события CDI - это путь?Класс продюсера наблюдает за событием и устанавливает динамические данные в классе производителя, используемом при создании EntityManager? Как обновить точки впрыска при изменении базы данных? –