【发布时间】:2014-11-13 12:07:39
【问题描述】:
我已经为这个问题苦苦挣扎了好几天,
这是场景: 我有几个数据库,每个客户都有一个,所有这些数据库都具有相同的 结构(相同的表和列),所以我的应用程序需要在运行时决定它需要连接哪个。我正在使用 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) 并且仍然能够使用的方法 传递数据源?
【问题讨论】:
-
为什么不能注入数据源名称?还是从属性文件中读取?
-
我只是找不到一种方法来同时使用@PersistenceContext
标签: java database ejb eclipselink entitymanager