JPA动态持久性单元名称 [英] JPA dynamic persistence unit name

查看:118
本文介绍了JPA动态持久性单元名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need a way to dynamically specify the persistence unit in a EJB.

简化示例:

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

I have an application using multiple databases as data stores. Each of the data stores are structurally the same. Depending on the client connecting to the application I need to access the data from a specific data store.

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

Therefore, I would like to use the same EJB so that the business logic is not duplicated, but then just select the correct persistence unit based on the client.

到目前为止我已经仅直接向实体管理器注入硬编码的持久性单元名称。
有没有办法可以动态地为实体管理器注入附加到EJB的所需持久性单元?
此外,可以在运行时动态添加持久性单位吗?
我当前必须在persistence.xml文件中指定持久性单元。
理想情况下,我想在系统运行时根据需要在服务器jdbc / db1,jdbc / db2等上创建池。然后将这些添加到中央客户端数据库并将其链接到客户端,以便在客户端连接时,它将检查池的名称,并在调用EJB以获取持久性单元时使用它。

Up to this point I've only directly injected the entity manager with the persistence unit name hard coded. Is there a way I can dynamically inject the entity manager with the required persistence unit attached to the EJB? Also, can persistence units be added dynamically during runtime? I currently have to specify the persistence unit in the persistence.xml file. Ideally I would like to create pools on the server jdbc/db1, jdbc/db2 etc as required while the system is running. Then just add these to the central client database and link it to a client, so that when the client connects, it will check the name of the pool, and use it when calling the EJB to get the persistence unit.

我还是Java EE开发的新手。任何帮助将不胜感激。

I'm still really new to Java EE development. Any help would be greatly appreciated.

推荐答案

在当前的JPA版本中,遗憾的是无法动态创建持久性单元。如果此功能对您很重要,您可以考虑在JPA问题跟踪器上为其创建JIRA问题: http: //java.net/jira/browse/JPA_SPEC

In the current JPA version, it's unfortunately not possible to create persistence units dynamically. If this functionality it's important for you, you could consider creating a JIRA issue for it at the JPA issue tracker: http://java.net/jira/browse/JPA_SPEC

使用 @PersistenceContext 注释,它是也无法动态选择特定的持久性单元。这实际上是分片的领域,Hibernate曾试图解决但后来突然停止了。请参见 http://www.hibernate.org/subprojects/shards.html

Using the @PersistenceContext annotation, it's also not possible to dynamically select a specific persistence unit. This is actually the domain of sharding, which Hibernate once tried to address but then suddenly discontinued. See http://www.hibernate.org/subprojects/shards.html

但是你可以采取一些措施来获得类似的效果。

There are however a few thing you could do to get a similar effect.

一种方法是创建一个无状态EJB / CDI工厂bean,您注入所有实体管理器。这个成本是微不足道的,因为这些bean将被合并,实体经理一开始就没那么昂贵。

One approach is to create a Stateless EJB/CDI factory bean, that you inject with all your entity managers. The cost of this is marginal, since those beans will be pooled and entity managers are not that expensive to be created in the first place.

如果你也想注入它们根据某些条件,这个条件必须从上下文中获得,或者必须在注入点指定(但如果你这样做,你也可以直接注入正确的实体管理器)。

If you also want to inject them based on some condition, then this condition will have to be available from the context or has to be specified at the injection point (but if you would do that, you could just as well inject the right entity manager directly).

启动示例:

@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中:

And then in your beans:

@Stateless
public class SomeBean {

    @Inject @ShardedPersistenceContext
    private EntityManager entityManager;

    // ...
}

请注意这里需要Seam Persistence来获取 @TransactionScoped 注释。忘记透明地注入实体管理器并注入 ShardingEntityManagerFactory 并手动从中获取正确的实体管理器也可能更容易,但更冗长一点。

Note that you would need Seam Persistence here for the @TransactionScoped annotation. It also might be easier, but a little more verbose, to forget about injecting the entity manager transparently and inject the ShardingEntityManagerFactory instead and obtain the right one from it manually.

这篇关于JPA动态持久性单元名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆