我几天来一直在努力解决这个问题,
以下是该方案: 我有几个数据库,每个客户一个,所有数据库都是相同的 结构(相同的表和列),所以我的应用程序需要在运行时决定它需要连接哪一个。我正在使用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)的方法仍然可以 传递数据源?
答案 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;
这应该有用,虽然我没有测试它。