2014-09-19 138 views
2

我一直在努力解决这个问题的日子里,管理多个数据库连接

下面是这种情况: 我有几个数据库,为每个客户我公司,它们都具有相同的结构 (同表和列),所以我的应用程序需要在运行时决定它需要连接哪一个。我正在使用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()和 commit())。我可以使用@PersistenceContext注释使其工作,但是我不会让EntityManagerFactory传递数据源。

有谁知道使用容器管理事务(CMT)的方式,仍然可以通过 传递数据源?

+0

为什么你不能注入数据源名称?或从属性文件中读取它? – 2014-09-19 01:08:31

+0

我只是无法找到一种方法来执行此操作,并同时使用@PersistenceContext – 2014-09-19 01:15:14

回答

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; 

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

+0

我已经试过了,它工作正常,但是如果其中一个连接失败,应用程序将无法部署。 – 2014-09-19 12:49:26

+0

也许它可以克服。你有什么样的错误? – zbig 2014-09-19 12:52:24

+0

就像这样 - >内部异常:java.sql.SQLException:分配连接时出错。原因:无法分配连接,因为:连接尝试失败。 – 2014-09-19 13:04:12