首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >能够在应用程序中动态切换持久性单元(JPA)

能够在应用程序中动态切换持久性单元(JPA)
EN

Stack Overflow用户
提问于 2010-05-04 21:23:15
回答 3查看 6.2K关注 0票数 4

我的应用程序数据访问层是使用Spring和EclipseLink构建的,我目前正在尝试实现以下特性--能够为用户动态切换当前/活动持久化单元。我尝试了各种选择,最终完成了以下操作。

在persistence.xml中,声明多个PU。创建一个与定义的PU数量一样多的EntityManagerFactory属性类。这将充当一个工厂,并根据我的逻辑返回适当的EntityManager

代码语言:javascript
运行
复制
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
 }
}

我的spring-beans xml看起来像这样。

代码语言:javascript
运行
复制
<!--  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新手,我知道这不是最好的解决方案。我非常感谢任何帮助我以更好/优雅的方式实现这个要求的人!

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-13 03:56:20

首先,感谢user332768和bert。我尝试使用bert提供的链接中提到的AbstractRoutingDataSource,但是在尝试连接我的jpa层(eclipselink)时迷路了。我恢复了我的旧方法,并做了一些修改。该解决方案看起来更干净(IMHO),并且运行良好。(在运行时切换数据库,并在同一事务中写入多个数据库)

代码语言:javascript
运行
复制
public class MyEntityManagerFactoryImpl implements MyEntityManagerFactory, ApplicationContextAware {

    private HashMap<String, EntityManagerFactory> emFactoryMap;

    public EntityManager getEntityManager(String releaseId) {
        return SharedEntityManagerCreator.createSharedEntityManager(emFactoryMap.get(releaseName));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        Map<String, LocalContainerEntityManagerFactoryBean> emMap = applicationContext.getBeansOfType(LocalContainerEntityManagerFactoryBean.class);
        Set<String> keys = emMap.keySet();
        EntityManagerFactory entityManagerFactory = null;
        String releaseId = null;
        emFactoryMap = new HashMap<String, EntityManagerFactory>();
        for (String key:keys) {
            releaseId = key.split("_")[1];
            entityManagerFactory = emMap.get(key).getObject();
            emFactoryMap.put(releaseId, entityManagerFactory);
        }
    }
}

我现在用MyEntityManagerFactoryImpl的一个实例(单例)注入我的DAO。然后,dao将简单地调用具有所需版本的createSharedEntityManager,并将获得该数据库的正确EntityManager。(请注意,我现在使用的是应用程序管理的EntityManager,因此我必须在我的dao中显式地关闭它们)

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

代码语言:javascript
运行
复制
...
<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"/>
....

干杯!(欢迎评论)

票数 1
EN

Stack Overflow用户

发布于 2010-05-05 04:10:11

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

代码语言:javascript
运行
复制
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();
票数 0
EN

Stack Overflow用户

发布于 2010-05-06 03:45:25

这也是我将来需要做的事情,为此我将Spring DynamicDatasourceRouting加入了书签

http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2765631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档