Динамический атрибут @PersistenceContext unitName для контейнерного EntityManager
в основном, что я хочу сделать, это присвоить атрибуту 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, я не могу сообщить серверу приложений, какая БД (единица непрерывности) она должна использовать на время
любая помощь будет оценена
Ответы
Ответ 1
Значения аннотаций не могут быть назначены во время выполнения, поэтому вам нужно будет найти стратегию, в которой вы можете создать несколько PersistenceContext
s. Если вы можете использовать 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
.
Ответ 2
Вам нужно использовать управляемый приложением ресурс, а не контейнер.
то есть.
Persistence.createEntityManagerFactory()
Вы все еще можете использовать JTA, а не инъекцию.