在JBoss WildFly上使用JPA 2.1和JTA的动态数据源

时间:2015-09-27 09:13:49

标签: jpa jboss wildfly multi-tenant jta

我对使用JPA和JTA的Jboss WildFly9感到生气。 在我的项目需求中,我必须实现多租户,因此我必须在persistence.xml中动态更改数据源。

使用jee方法这是不可能的,所以有人建议我使用经典:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery"); 
EntityManager em = emf.createEntityManager();

所以到现在为止,我可以自己创建enetitymanager,我可以在hashmap(包含数据源)中设置jpa属性。

现在我想使用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 个答案:

答案 0 :(得分:1)

Hibernate有自己的multi-tenancy解决方案。这不是JPA标准的一部分,但它与它兼容并且基本上与它正交。

它与托管持久性单元一起使用,并且与JTA兼容。

我在WildFly 8.2.0.Final和9.0.1.Final上成功使用了SCHEMA策略。

您只需要实现两个辅助类并在persistence.xml中配置它们。

答案 1 :(得分:0)

如果您可以事先告诉您需要多少数据源,那么您可以使用CDI生产者模式实现某种实体管理器的上下文选择。

在persistence.xml中定义所有可能的数据源,然后使用某种生成器singleton工厂类根据其持久性单元注入它们。

创建一个生成器方法,根据您当前的上下文选择正确的实体管理器。

然后在你的ejb或cdi bean中通过CDI注入获取entitymanager的实例

@注入 私有EntityManager em