如何在 WebLogic 12c 中使用编译时未知的数据源创建 JTA 感知 EntityManager?
How can I create a JTA-aware EntityManager in WebLogic 12c with a data-source not known at compile time?
我正在开发一个部署在 WebLogic 12c 中的应用程序,它需要能够在运行时获取连接到任意数据源的 JPA EntityManager (EclipseLink 2.5.2)。我目前不知道该数据源的 JNDI 名称是什么;会有几个到很多,连接到不同的数据库,但都具有相同的模式。所以不能在应用程序里面的persistence.xml中指定数据源名称;它必须来自外部(最有可能是配置文件)。
我认为我无法注入 EntityManagerFactory 或 EntityManager;它们与 persistence.xml 中的配置紧密耦合,我似乎无法覆盖 JTA 数据源名称。例如,这 不 工作:
@PersistenceUnit(unitName="myPU")
private EntityManagerFactory emf;
// ...
Map<String, Object> emProps = new HashMap<String, Object>();
emProps.put(EntityManagerProperties.JTA_DATASOURCE, "jdbc/foobar");
EntityManager em = emf.createEntityManager(emProps);
我在这里作为我的 EntityManager 仍然连接到 persistence.xml 中实际指定的 JTA 数据源。
所以我开始考虑通过非注入方式创建 EntityMangerFactory,例如 Persistence.createEntityManagerFactory(puName, propMap)
但在这里,似乎无论 persistence.xml 或 我的 属性 地图说,我得到一个 RESOURCE_LOCAL
EntityManagerFactory!
如何获得启用 JTA 的 EntityManager 或 EntityManagerFactory 和 与编译时未知的任意数据源名称相关联?
至少在 EclipseLink 2.5.2 中是这样:
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
properties.put(PersistenceUnitProperties.JTA_DATASOURCE, "jdbc/foobar");
emf = Persistence.createEntityManagerFactory("myPU", properties);
JpaEntityManagerFactory jemf = (JpaEntityManagerFactory)emf;
WebLogicTransactionController wlstx = new WebLogicTransactionController();
if (jemf.getDatabaseSession() != null && jemf.getDatabaseSession().getExternalTransactionController() == null) {
jemf.getDatabaseSession().setExternalTransactionController(wlstx);
}
if (jemf.getServerSession() != null && jemf.getServerSession().getExternalTransactionController() == null) {
jemf.getServerSession().setExternalTransactionController(wlstx);
}
通过将事务控制器添加到 EMF,它再次被 JTA 征用并将遵守 JTA 事务。我的 persistence.xml 为 JTA 数据源提供了一个虚拟值;我在代码中重写了,我们走了!
注意:目前getDatabaseSession()
和getServerSession()
实际上return是完全相同的对象。我可以只设置其中一个,但这是没有记录的,你最好安全地设置两个,只是为了确定。
我正在开发一个部署在 WebLogic 12c 中的应用程序,它需要能够在运行时获取连接到任意数据源的 JPA EntityManager (EclipseLink 2.5.2)。我目前不知道该数据源的 JNDI 名称是什么;会有几个到很多,连接到不同的数据库,但都具有相同的模式。所以不能在应用程序里面的persistence.xml中指定数据源名称;它必须来自外部(最有可能是配置文件)。
我认为我无法注入 EntityManagerFactory 或 EntityManager;它们与 persistence.xml 中的配置紧密耦合,我似乎无法覆盖 JTA 数据源名称。例如,这 不 工作:
@PersistenceUnit(unitName="myPU")
private EntityManagerFactory emf;
// ...
Map<String, Object> emProps = new HashMap<String, Object>();
emProps.put(EntityManagerProperties.JTA_DATASOURCE, "jdbc/foobar");
EntityManager em = emf.createEntityManager(emProps);
我在这里作为我的 EntityManager 仍然连接到 persistence.xml 中实际指定的 JTA 数据源。
所以我开始考虑通过非注入方式创建 EntityMangerFactory,例如 Persistence.createEntityManagerFactory(puName, propMap)
但在这里,似乎无论 persistence.xml 或 我的 属性 地图说,我得到一个 RESOURCE_LOCAL
EntityManagerFactory!
如何获得启用 JTA 的 EntityManager 或 EntityManagerFactory 和 与编译时未知的任意数据源名称相关联?
至少在 EclipseLink 2.5.2 中是这样:
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
properties.put(PersistenceUnitProperties.JTA_DATASOURCE, "jdbc/foobar");
emf = Persistence.createEntityManagerFactory("myPU", properties);
JpaEntityManagerFactory jemf = (JpaEntityManagerFactory)emf;
WebLogicTransactionController wlstx = new WebLogicTransactionController();
if (jemf.getDatabaseSession() != null && jemf.getDatabaseSession().getExternalTransactionController() == null) {
jemf.getDatabaseSession().setExternalTransactionController(wlstx);
}
if (jemf.getServerSession() != null && jemf.getServerSession().getExternalTransactionController() == null) {
jemf.getServerSession().setExternalTransactionController(wlstx);
}
通过将事务控制器添加到 EMF,它再次被 JTA 征用并将遵守 JTA 事务。我的 persistence.xml 为 JTA 数据源提供了一个虚拟值;我在代码中重写了,我们走了!
注意:目前getDatabaseSession()
和getServerSession()
实际上return是完全相同的对象。我可以只设置其中一个,但这是没有记录的,你最好安全地设置两个,只是为了确定。