lik*_*her 15 jpa java-ee ejb-3.1
我需要一种方法来动态指定EJB中的持久性单元.
简化示例:
我有一个应用程序使用多个数据库作为数据存储.每个数据存储在结构上都是相同的.根据连接到应用程序的客户端,我需要访问特定数据存储中的数据.
因此,我想使用相同的EJB,以便不重复业务逻辑,但只需根据客户端选择正确的持久性单元.
到目前为止,我只是直接向实体管理器注入硬编码的持久性单元名称.有没有办法可以动态地为实体管理器注入附加到EJB的所需持久性单元?此外,可以在运行时动态添加持久性单元吗?我目前必须在persistence.xml文件中指定持久性单元.理想情况下,我想在系统运行时根据需要在服务器jdbc/db1,jdbc/db2等上创建池.然后将这些添加到中央客户端数据库并将其链接到客户端,以便在客户端连接时,它将检查池的名称,并在调用EJB以获取持久性单元时使用它.
我还是Java EE开发的新手.任何帮助将不胜感激.
在当前的JPA版本中,遗憾的是无法动态创建持久性单元.如果此功能对您很重要,您可以考虑在JPA问题跟踪器上为它创建一个JIRA问题:http://java.net/jira/browse/JPA_SPEC
使用@PersistenceContext注释,也无法动态选择特定的持久性单元.这实际上是分片的领域,Hibernate曾试图解决但后来突然停止了.见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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的豆子里:
@Stateless
public class SomeBean {
@Inject @ShardedPersistenceContext
private EntityManager entityManager;
// ...
}
Run Code Online (Sandbox Code Playgroud)
请注意,此处需要Seam Persistence作为@TransactionScoped注释.忘记透明地注入实体管理器并注入ShardingEntityManagerFactory而不是手动从中获取正确的实体管理器也可能更容易,但更冗长一点.
| 归档时间: |
|
| 查看次数: |
11682 次 |
| 最近记录: |