我对使用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()
告诉我在创建实体经理时无法加入交易。
那么......我怎样才能尊重我的项目要求......用我的动态数据创建自己的持久性,同时使用事务管理器?
答案 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