Динамические источники данных с JPA 2.1 и JTA на JBoss WildFly
Я схожу с ума от Jboss WildFly9 с JPA и JTA. В требованиях моего проекта я должен реализовать мультитенантность, поэтому мне нужно динамически изменять источник данных внутри моего файла persistence.xml.
Используя джип-подход, это невозможно, поэтому кто-то предлагает мне использовать классику:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery");
EntityManager em = emf.createEntityManager();
Так что до сих пор это работает, я могу самостоятельно создать enetitymanager и установить свойства jpa в hashmap (включая источник данных).
Теперь я хочу использовать JTA хотя бы для обработки транзакций с помощью диспетчера транзакций.
Итак, вот свойства, которые я установил с помощью кода:
Properties properties = new Properties();
properties.put ("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("javax.persistence.provider", "org.hibernate.jpa.HibernatePersistenceProvider");
properties.put("javax.persistence.transactionType", "JTA");
properties.put("javax.persistence.jtaDataSource", dataSourcePath);
Тип транзакции сейчас - JTA. Поэтому я ожидаю, что я могу использовать такой код, как:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery");
EntityManager em = emf.createEntityManager();
MyEntity exUser= new MyEntity();
try{
Context context = new InitialContext();
UserTransaction userTransaction = (UserTransaction)context.lookup("java:comp/UserTransaction");
userTransaction.begin();
em.persist(exUser);
userTransaction.commit();
Конечно, этот код не работает вообще, поскольку Hibernate вызывает исключение:
java.lang.NullPointerException at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus()
Скажите мне, что я не смог присоединиться к транзакции при создании менеджера сущностей.
Итак... как я могу уважать требования моего проекта... создать свое постоянство с помощью динамического источника данных и в то же время с помощью диспетчера транзакций?
2 ответа
Hibernate имеет собственное решение для мультитенантности. Это не является частью стандарта JPA, но оно совместимо и во многом ортогонально ему.
Он работает с управляемыми единицами персистентности и совместим с JTA.
Я успешно использовал стратегию SCHEMA на WildFly 8.2.0.Final и 9.0.1.Final.
Вам просто нужно реализовать два вспомогательных класса и настроить их в своем persistence.xml
,
Если вы можете заранее сказать, сколько источников данных вам потребуется, вы можете реализовать некоторый контекстный отбор менеджеров сущностей с помощью шаблона производителя CDI.
Определите все возможные источники данных в своем файле persistence.xml, а затем используйте какой-нибудь класс фабрики-одиночки производителя для внедрения их в зависимости от их единицы сохраняемости.
Создайте метод продюсера, который выбирает правильного менеджера сущностей на основе вашего текущего контекста.
Затем в ваших бобах ejb или cdi получите экземпляр entitymanager посредством внедрения CDI
@Inject private EntityManager em