Динамические источники данных с 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

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