如何在WebLogic 12c中创建一个支持JTA的EntityManager,其数据源在编译时是未知的?

时间:2015-07-17 16:10:34

标签: jpa weblogic eclipselink jta

我正在开发一个应用程序,要部署在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?

1 个答案:

答案 0 :(得分:1)

这就是诀窍,至少在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数据源提供了一个虚拟值;我在代码中重写并离开了!

NB :目前getDatabaseSession()getServerSession()实际上返回完全相同的对象。我只能设置其中一个,但这没有记录,你最好安全地设置它们,只是为了确定。