gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 20:46:08 25 4
gpt4 key购买 nike

我需要一种在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com