我需要一种方法来动态指定 EJB 中的持久性单元。
简化示例:
我有一个使用多个数据库作为数据存储的应用程序。
每个数据存储在结构上都是相同的。
根据连接到应用程序的客户端,我需要从中访问数据
特定的数据存储。
因此,我想使用相同的EJB,这样业务逻辑就不会重复,
然后只需根据客户端选择正确的持久性单元即可。
到目前为止,我只是直接向实体管理器注入了硬编码的持久性单元名称。
有没有一种方法可以动态注入实体管理器并将所需的持久性单元附加到 EJB?
另外,持久化单元可以在运行时动态添加吗?
我目前必须在 persistence.xml 文件中指定持久性单元。
理想情况下,我想在系统运行时根据需要在服务器 jdbc/db1、jdbc/db2 等上创建池。然后只需将它们添加到中央客户端数据库并将其链接到客户端,这样当客户端连接时,它将检查池的名称,并在调用 EJB 时使用它来获取持久性单元。
我对 Java EE 开发还很陌生。任何帮助将不胜感激。
遗憾的是,在当前的 JPA 版本中,无法动态创建持久性单元。如果此功能对您很重要,您可以考虑在 JPA 问题跟踪器中为其创建 JIRA 问题:http://java.net/jira/browse/JPA_SPEC http://java.net/jira/browse/JPA_SPEC
使用@PersistenceContext
注释,也不可能动态选择特定的持久单元。这实际上是分片的领域,Hibernate 曾经试图解决这个问题,但后来突然停止了。看http://www.hibernate.org/subprojects/shards.html http://www.hibernate.org/subprojects/shards.html
然而,您可以采取一些措施来获得类似的效果。
一种方法是创建一个无状态 EJB/CDI 工厂 bean,将其与所有实体管理器一起注入。这样做的成本是微不足道的,因为这些 Bean 将被集中起来,并且实体管理器的创建成本并不高。
如果您还想根据某些条件注入它们,那么该条件必须从上下文中可用,或者必须在注入点指定(但如果您愿意这样做,您也可以注入正确的实体管理器直接地)。
一个启动示例:
@Stateless
@TransactionAttribute(SUPPORTS)
public class ShardingEntityManagerFactory {
@Resource
private SessionContext sessionContext;
@PersistenceContext(unitName = "pu1")
private EntityManager entityManager1;
@PersistenceContext(unitName = "pu2")
private EntityManager entityManager2;
@Produces @TransactionScoped @ShardedPersistenceContext
public EntityManager getEntityManager() {
if (sessionContext.isCallerInRole("FOO")) {
return entityManager1;
} else {
return entityManager2;
}
}
}
然后在你的豆子中:
@Stateless
public class SomeBean {
@Inject @ShardedPersistenceContext
private EntityManager entityManager;
// ...
}
请注意,您需要在此处使用 Seam Persistence@TransactionScoped
注解。忘记透明地注入实体管理器并注入ShardingEntityManagerFactory
相反,并从中手动获取正确的一个。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)