管理多个数据库连接

时间:2014-09-19 00:54:53

标签: java database ejb eclipselink entitymanager

我几天来一直在努力解决这个问题,

以下是该方案: 我有几个数据库,每个客户一个,所有数据库都是相同的 结构(相同的表和列),所以我的应用程序需要在运行时决定它需要连接哪一个。我正在使用JPA2,EclipseLink和EJB3。

我的第一次尝试是使用所有逻辑来实现自定义EntityManager以在正确的数据库上执行操作,然后我将此EntityManager配置为无状态EBJ,以便可以使用@EBJ注释注入它(如在此链接中描述:http://www.hostettler.net/blog/2012/11/20/multi-tenancy/)。我不能让它工作,因为它在尝试注入EntityManager时抛出异常。

所以我决定尝试别的东西,我已经创建了EntityManagerFactory并且我通过了 JTA_DATASOURCE到它(在运行时决定使用哪一个),所以它可以连接到 正确的数据库。

以下是代码:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestEntDAO {

    private EntityManager em;
    private EntityManagerFactory emf;

    @PostConstruct
    public void init() {
        em = getEntityManager();
    }

    public EntityManager getEntityManager() {
        Map props = new HashMap();
        props.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
        props.put(PersistenceUnitProperties.JTA_DATASOURCE, dataSourceName());
        emf = Persistence.createEntityManagerFactory("testePU", props);
        em = emf.createEntityManager();
        return em;
    }

    public String dataSourceName(){
        if(someCondition){
            return "db1";
        }else{
            return "db2";
        }
    }
}

这完美地运作,唯一的问题是交易不是由管理的 容器,所以我必须明确标记事务的边界(调用begin()和 承诺())。我可以使用@PersistenceContext注释使其工作,但后来我 没有EntityManagerFactory来传递数据源。

有没有人知道使用容器管理事务(CMT)的方法仍然可以 传递数据源?

1 个答案:

答案 0 :(得分:0)

也许尝试定义3个数据源和3个持久性单元。

<persistence-unit name="PU1">
  <jta-data-source>jdbc/DS1</jta-data-source>
  ...
</persistence-unit>
<persistence-unit name="PU2">
  <jta-data-source>jdbc/DS2</jta-data-source>
  ...
</persistence-unit>
<persistence-unit name="PU3">
  <jta-data-source>jdbc/DS3</jta-data-source>
  ...
</persistence-unit>

从您想要的任何持久性单元注入实体管理器。

@PersistenceContext(unitName = "PU2")
EntityManager em;

这应该有用,虽然我没有测试它。