JavaEE6:如何通过登录信息为EntityManager选择持久化单元

JavaEE6:如何通过登录信息为EntityManager选择持久化单元,java,persistence,java-ee-6,entitymanager,jboss7.x,Java,Persistence,Java Ee 6,Entitymanager,Jboss7.x,我需要根据登录会话在JavaEE6项目(JBoss7)中选择EntityManager。 用户“Peter”将使用数据库dbPeter,用户“Paul”将使用数据库dbPaul 现在的问题是,如何生成自动绑定到相应数据库/持久化单元的实体管理器 我使用CDI注入EntityManager。因此,我的第一步是让EntityManager的生产者从会话中查找登录信息并选择数据库。 那么,如何在这个过程中选择数据库/持久性上下文呢?? 由于Jboss7,我再也看不到持久化单元的任何jndi条目,因此不

我需要根据登录会话在JavaEE6项目(JBoss7)中选择EntityManager。 用户“Peter”将使用数据库dbPeter,用户“Paul”将使用数据库dbPaul

现在的问题是,如何生成自动绑定到相应数据库/持久化单元的实体管理器

我使用CDI注入EntityManager。因此,我的第一步是让EntityManager的生产者从会话中查找登录信息并选择数据库。 那么,如何在这个过程中选择数据库/持久性上下文呢?? 由于Jboss7,我再也看不到持久化单元的任何jndi条目,因此不能考虑jndi查找

我试着用

@Produces
public EntityManager produceEM() {
    EntityManagerFactory managerFactory = Persistence.createEntityManagerFactory( "dbPaul" );

    return managerFactory.createEntityManager();
}
但这在部署时失败

HH000231:架构导出失败:java.sql.SQLException:您无法在托管事务期间设置自动提交

这没关系,因为注入em的地方主要在事务内部。
有人有想法吗?

首先,我不愿意动态创建一个
EntityManagerFactory
。我想您必须在每一个DAO实例创建中(或在访问数据库时使用的任何EJB对象中)这样做。如果是这种情况,请三思:创建
EntityManagerFactory
非常昂贵,通常应该在应用程序生命周期中完成一次。作为替代方案,我可能会为每个持久化单元创建不同的DAO,将使用其中一个的责任转移到上层,以便您仍然可以依赖容器来创建
EntityManager

也就是说,在您的上下文中,假设方法produceEM()位于EJB中,并且您使用的是容器管理的安全性,您可以通过以下方式注入EJBContext:

@Resource
EJBContext ejbContext;
从这里您可以获取
主体
,并根据它创建EntityManager

如果任何假设无效,请告诉我,并尝试更新我的答案

编辑:

@Stateless
public class EntityManagerService {

   @Resource
   EJBContext ejbContext;

   @Produces
   public EntityManager produceEM() {

   EntityManagerFactory managerFactory = Persistence.createEntityManagerFactory(ejbContext.getCallerPrincipal().getName());

   return managerFactory.createEntityManager();

   }
}

您还可以在用户名和数据库名之间创建自己的映射,如果您想在两者之间实现某种解耦,这可能是一个好主意。

这不完全是您问题的答案,但您考虑过JPA多租户吗?AFAIK Hibernate和EclipseLink都支持它。

好吧,您对EntityManager工厂的看法是正确的。在我的例子中,我不知道生产环境中将有多少个持久性单元。每个客户端都有一个数据库,但只有一个部署的webapp。因此,客户机的数量将增加,我非常确定操作系统不会为每个新客户机创建DAO=)。我需要的是一种将EntityManager绑定到持久性单元的通用方法,其中主要信息指向要使用的持久性单元。它仍然在说“java.sql.SQLException:您不能在托管事务期间设置自动提交!”谢谢您的提示,但反过来说=)我需要为每个客户设置一个数据库。这就是我老板想要的。这家伙向你展示了如何在Hibernate中做你想做的事。本质上是一个考虑数据库分配的ConnectionProvider。看起来您需要为您的用户信息设置不同的持久化单元,您需要尽快设置租户id,如果您进行跨线程或跨VM调用,您可能会遇到麻烦。