Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 在应用程序(JPA)中动态切换持久性单元的能力_Spring_Jpa_Eclipselink - Fatal编程技术网

Spring 在应用程序(JPA)中动态切换持久性单元的能力

Spring 在应用程序(JPA)中动态切换持久性单元的能力,spring,jpa,eclipselink,Spring,Jpa,Eclipselink,我的应用程序数据访问层是使用Spring和EclipseLink构建的,我目前正在尝试实现以下功能—为用户动态切换当前/活动持久化单元的能力。我尝试了各种选择,最后做了以下几点 在persistence.xml中,声明多个pu。创建一个类,该类的EntityManagerFactory属性数量与定义的属性数量相同。这将作为工厂,并根据我的逻辑返回相应的EntityManager public class MyEntityManagerFactory { @PersistenceUnit(un

我的应用程序数据访问层是使用Spring和EclipseLink构建的,我目前正在尝试实现以下功能—为用户动态切换当前/活动持久化单元的能力。我尝试了各种选择,最后做了以下几点

在persistence.xml中,声明多个pu。创建一个类,该类的EntityManagerFactory属性数量与定义的属性数量相同。这将作为工厂,并根据我的逻辑返回相应的EntityManager

public class MyEntityManagerFactory {
  @PersistenceUnit(unitName="PU_1")
  private EntityManagerFactory emf1;

  @PersistenceUnit(unitName="PU_2")
  private EntityManagerFactory emf2;

  public EntityManager getEntityManager(int releaseId) {
    // Logic goes here to return the appropriate entityManeger
 }
}
我的SpringBeans xml如下所示

<!--  First persistence unit  -->    
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emFactory1">
  <property name="persistenceUnitName" value="PU_1" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager1">
  <property name="entityManagerFactory" ref="emFactory1"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager1"/>

第二个PU重复上述部分(名称如emFactory2、transactionManager2等)

我是JPA新手,我知道这不是最好的解决方案。我感谢您以更好/优雅的方式帮助我实现这一要求


谢谢

我不确定这是否是一种干净的方法。我们可以使用spring应用程序上下文来获取在spring application.xml中声明的entitymanagerfactory,而不是多次声明enitiymanagerfactory

hm = applicationContext.getBeansOfType(org.springframework.orm.jpa.LocalEntityManagerFactoryBean.class);
EntityManagerFactory emf = ((org.springframework.orm.jpa.LocalEntityManagerFactoryBean) hm.get("&emf1")).getNativeEntityManagerFactory();
EntityManagerFactory emf2 = ((org.springframework.orm.jpa.LocalEntityManagerFactoryBean) hm.get("&emf2")).getNativeEntityManagerFactory();

这也是我将来需要做的事情,为此我将SpringDynamicDataSourceRouting作为书签


据我所知,这是使用一个PU,它被分配不同的数据源。也许这会有帮助。

首先要感谢用户332768和bert。我尝试使用AbstractRoutingDataSource,如bert提供的链接中所述,但在尝试连接我的jpa层(eclipselink)时迷失了方向。经过一些修改,我又回到了以前的方法。该解决方案看起来更干净(IMHO),效果良好。(在运行时切换数据库,并在同一事务中写入多个数据库)

公共类MyEntityManagerFactoryImpl实现MyEntityManagerFactory,ApplicationContextAware{
私有HashMap-emFactoryMap;
公共EntityManager getEntityManager(字符串释放ID){
返回SharedEntityManager.createSharedEntityManager(emFactoryMap.get(releaseName));
}
@凌驾
public void setApplicationContext(ApplicationContext ApplicationContext)
抛出BeansException{
Map emMap=applicationContext.getBeansOfType(LocalContainerEntityManagerFactoryBean.class);
Set keys=emMap.keySet();
EntityManagerFactory EntityManagerFactory=null;
字符串releaseId=null;
emFactoryMap=新HashMap();
用于(字符串键:键){
releaseId=key.split(“”)[1];
entityManagerFactory=emMap.get(key.getObject();
emFactoryMap.put(releaseId,entityManagerFactory);
}
}
}
现在,我将我的DAO注入MyEntityManagerFactoryImpl的一个实例(单例)。然后dao将调用具有所需版本的createSharedEntityManager,并将获得该数据库的正确EntityManager。(注意,我现在使用的是应用程序管理的EntityManager,因此我必须在dao中显式关闭它们)

我还转到了jta事务管理器(管理跨多个数据库的事务) 这就是我的SpringXML现在的样子

...
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel1">
        <property name="persistenceUnitName" value="PU1" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel2">
        <property name="persistenceUnitName" value="PU2" />
</bean>

<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="jtaTransactionManager">
</bean>
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
....
。。。
....
干杯!(欢迎评论)

...
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel1">
        <property name="persistenceUnitName" value="PU1" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="em_Rel2">
        <property name="persistenceUnitName" value="PU2" />
</bean>

<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="jtaTransactionManager">
</bean>
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
....