динамический атрибут @PersistenceContext unitName для контейнерного EntityManager - PullRequest
10 голосов
/ 09 января 2012

По сути, я хочу назначить атрибуту unitName ' @ PersistenceContext значение, которое я получу из сеанса во время выполнения.

в деталях;

мое приложение будет SaaS-приложением, и у меня будут отдельные БД для разных арендаторов.я использую Glassfishv3 и управляю сущностями на основе контейнера , поэтому я не получаю ни одного экземпляра из EntityManagerFactory в явном виде.Все, что я делаю для создания менеджера сущностей:

@PersistenceContext(unitName = "DBNAME")
private EntityManager entityManager;

Мне нужно передать атрибут 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);

маловероятно, что в моем приложении контейнер выполняет эту работу, поэтому я не могу этого сделать

EntityManager em = emf.createEntityManager(props);

Несмотря на то, что у меня есть все единицы и классы персистентности в моем persistence.xml отиспользуя определения JNDI, я не могу сообщить серверу приложений, какую БД (единицу сохраняемости) он должен использовать во время

, любая помощь будет оценена

Ответы [ 2 ]

9 голосов
/ 09 января 2012

Значения в аннотациях не могут быть назначены во время выполнения, и поэтому вам нужно будет найти стратегию, в которой вы можете создать несколько PersistenceContext с.Если вы сможете использовать 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;
     }
  }

Затем вы можете использовать метод продюсера, например, в вашем DAO:

@Inject private EntityManager entityManager;

EDIT: Я бы порекомендовал использовать аннотацию @Qualifier, чтобы было понятно, откуда вы берете EntityManager.

1 голос
/ 09 января 2012

Вам необходимо использовать управляемый приложением модуль персистентности, а не контейнер.

т.е. Persistence.createEntityManagerFactory ()

Вы все еще можете использовать JTA, но не инъекцию.

...