在条件下在无状态会话 Bean 中注入特定的 EntityManager
Posted
技术标签:
【中文标题】在条件下在无状态会话 Bean 中注入特定的 EntityManager【英文标题】:inject specific EntityManager in stateless SessionBean on condition 【发布时间】:2012-10-22 06:04:56 【问题描述】:我目前正在处理调用无状态会话 Bean 以与数据库交互的 Web 应用程序。我的问题是关于这样的应用程序如何调用同一个会话 bean,以便后者可以选择必须使用哪个实体管理器来访问数据库。
目前我管理这种情况,启动不同的 Jboss 实例,监听不同的端口,并且在每个实例中我部署了相同的会话 Bean 池,并且一个或多个 Web 应用程序必须处理相同的数据库。换句话说,每个 Jboss 实例都包含一定数量的 Web 应用程序、一个持久性单元(persistence.xml in META-INF jar containing the @Entity's)
和会话 bean 池都在一个耳朵内。
主要弱点在哪里是不言而喻的:我需要处理更多不同的数据库,我必须维护尽可能多的 Jboss 实例,这主要是不可持续的,但不仅是因为资源原因。
我的最后一个问题是:部署不同的 Web 应用程序调用会话 bean 的最佳做法是什么?
提前致谢
Stfn
【问题讨论】:
【参考方案1】:使用 CDI @Producer
方法执行此操作。我假设您知道如何区分您拥有的众多 @PersistenceContext
s,因此您制作了一个制作人,如下所示:
// first inject all the entity managers that you have into your CDI producer
@PersistenceContext(name = "name0")
private EntitManager em0;
@PersistenceContext(name = "name1")
private EntitManager em1;
@PersistenceContext(name = "name2")
private EntitManager em2;
...
// then have your producer method with logic to chose the right EntityManager to be returned
@Produces @MyPersistenceContext
public EntityManager obtainTheRightEM(InjectionPoint caller)
if (hasCondition0(caller))
return em0;
else if (hasCondition1(caller))
return em1;
else if (hasCondition2(caller))
return em2;
else
...
然后在您的@EJB
s 中将@PersistenceContext
替换为@Inject @MyPersistenceContext
。
此外,根据您的特定问题,可能需要也可能不需要创建@MyPersistenceContext
限定符。如果您有特定的配置值,您需要向下传递给生产者,以便决定从生产者返回哪个EntityManager
,请考虑在您的自定义限定符中使用一些@Nonbinding
字段.
您最终可能会因为只有一个 @EJB
部署而侥幸。
干杯!希望这会有所帮助。
【讨论】:
【参考方案2】:你想要达到的目标并不是很清楚......
是否使用不同的数据库来分离来自不同客户的数据(每个数据库具有相同的结构)?为此,Hibernate 提供了一些多租户支持 (http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html),但 JPA 中尚未标准化。
您可以通过任何方式将不同的耳朵放在同一个 Jboss 实例上(您将需要使用不同的 Web 上下文名称)以减少资源消耗。 (但是您将失去操作系统级别的进程控制,一个租户可以使用所有资源而无法确保另一个租户获得最少的资源。)
【讨论】:
非常感谢 Kazaag 的回答。让我再解释一下。 非常感谢您的回答。让我再解释一下。数据库不同但具有相同的关系。我已经尝试过您概述的第二个解决方案,但不起作用。在同一个容器中(这是我的第一次尝试)我有会话 Bean 冲突(使用了第一个调用的会话 bean对于后续请求,无论应用程序是否调用 id,在会话 bean 池级别缺乏隔离),唯一的方法是重命名会话 bean 接口,这是我为了维护更轻量的代码而避免的。所以,让我试验第一个概述的解决方案。 Stfn 如果 EJB 位于不同的耳朵,它们应该有不同的全局名称,因此通过 JNDI 检索它们应该会给您相应的名称。以上是关于在条件下在无状态会话 Bean 中注入特定的 EntityManager的主要内容,如果未能解决你的问题,请参考以下文章