基于容器的EntityManager的动态@PersistenceContext unitName属性

Joe*_*vac 10 jpa eclipselink java-ee ejb-3.0 glassfish-3

基本上,我想做的是为@PersistenceContext分配' unitName '属性,其值是我将在运行时从Session获得的.

详情;

我的应用程序将是一个SaaS应用程序,我将为每个不同的租户提供单独的数据库.我正在使用Glassfishv3并管理基于容器的实体,所以我没有明确地从EntityManagerFactory获取任何实例.我为创建实体经理所做的一切都是;

@PersistenceContext(unitName = "DBNAME")
private EntityManager entityManager;
Run Code Online (Sandbox Code Playgroud)

我需要根据当前用户传递unitName属性.它不应该是硬编码的.

我已经更新了Eclipselink 2.3但是所有的例子都是从EMF创建一个实例,你可以传递属性Map

Map memberProps = new HashMap();
memberProps.put("memberPu1", props1);
memberProps.put("memberPu2", props2);

Map props = new HashMap();
props.put("eclipselink.jdbc.exclusive-connection.mode", "Always");
props.put("eclipselink.composite-unit.properties", memberProps);

EntityManager em = emf.createEntityManager(props);
Run Code Online (Sandbox Code Playgroud)

不太可能在我的应用程序中,容器执行该工作,所以我无法做到这一点

EntityManager em = emf.createEntityManager(props);
Run Code Online (Sandbox Code Playgroud)

即使我在我所有的持久化单元和类的persistence.xml使用JNDI定义,我不能够告诉它DB(持久性单元),它应该在当时使用的应用程序服务器

任何帮助,将不胜感激

Gon*_*gui 9

注释中的值无法在运行时分配,因此您需要找到可以创建多个PersistenceContexts 的策略.如果你可以使用CDI,它可能会让你的生活更轻松.

使用CDI,您可以创建生产者,如下所示:

public class EntityManagerProducer {

  @PersistenceContext(unitName="firstUnit") private EntityManager firstEntityManager;
  @PersistenceContext(unitName="secondUnit") private EntityManager secondEntityManager;

  @Produces
  public EntityManager getEntityManager(InjectionPoint injectionPoint) {
     if(<your_first_criteria>) {
       return firstEntityManager;
     } else if (<your_second_criteria>) {
       return secondEntityManager;
     }
  }
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的DAO中使用你的生成器方法:

@Inject private EntityManager entityManager;
Run Code Online (Sandbox Code Playgroud)

编辑:我可能会建议使用@Qualifier注释,因为它清楚地表明你EntityManager从哪里获得.