jakarta-ee - JPA 动态持久化单元名称

标签 jakarta-ee jpa ejb-3.1

我需要一种在 EJB 中动态指定持久性单元的方法。

简化示例:

我有一个使用多个数据库作为数据存储的应用程序。
每个数据存储在结构上都是相同的。
根据连接到应用程序的客户端,我需要从中访问数据
特定的数据存储。

因此,我想使用相同的EJB,这样业务逻辑就不会重复,
但随后只需根据客户端选择正确的持久性单元。

到目前为止,我只是直接将持久性单元名称硬编码注入(inject)实体管理器。
有没有一种方法可以动态注入(inject)实体管理器,并将所需的持久性单元附加到 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,将其注入(inject)所有实体管理器。这样做的成本是微不足道的,因为这些 bean 将被汇集起来,而且实体管理器的创建成本并不高。

如果您还想根据某些条件注入(inject)它们,那么这个条件必须从上下文中可用或必须在注入(inject)点指定(但如果您愿意这样做,您也可以注入(inject)正确的实体管理器直接地)。

开球示例:

@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;
        }
    }
}

然后在你的 bean 里:
@Stateless
public class SomeBean {

    @Inject @ShardedPersistenceContext
    private EntityManager entityManager;

    // ...
}

请注意,@TransactionScoped 此处需要 Seam Persistence。注解。忘记透明地注入(inject)实体管理器并注入(inject) ShardingEntityManagerFactory 也可能更容易,但更冗长一些。而是手动从中获取正确的。

关于jakarta-ee - JPA 动态持久化单元名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9957179/

相关文章:

java - java验证码库的推荐

java - 为什么 REST Web 服务不支持 war 之外的 EJB 资源类?

java - Eclipse、Tomcat、JPA - java.lang.NoClassDefFoundError

jakarta-ee - 使用 JavaEE 6 WAR 与 EAR 封装 EJB

java - 使用 JPA 插入具有单列的连续表时出现 SQLGrammarException

Java EE 6 注入(inject)创建不同的策略

java - 为拥有的实体解耦服务的设计模式是什么?

java - 如何序列化一组枚举?

jakarta-ee - @Asynchronous 不会导致在 JBossAS7 中异步调用 EJB 方法

ejb-3.0 - 嵌入式 EJB 容器与实际服务器容器有什么区别