JavaEE6: Как выбрать единицу сохранения для менеджера сущностей по информации для входа - PullRequest
1 голос
/ 06 декабря 2011

Мне нужно выбрать EntityManager в моем проекте JavaEE6 (JBoss7) в зависимости от сеанса входа в систему.Пользователь "Peter" приведет к использованию базы данных dbPeter, а пользователь "Paul" приведет к использованию базы данных dbPaul.

Вопрос теперь в том, как я могу создать менеджер сущностей, который автоматически связывается с соответствующей базой данных/ постоянство юнит?

Я использую CDI для ввода EntityManager.Итак, мой первый шаг - создать продюсер EntityManager, который ищет информацию для входа в систему из сеанса и выбирает базу данных.Итак, как мне выбрать базу данных / постоянство контекста в этом prducer?Поскольку Jboss7 я больше не вижу ни одной записи jndi для модуля персистентности, поэтому поиск jndi не может быть рассмотрен.

Я попытался использовать

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

    return managerFactory.createEntityManager();
}

, но это не удается во время развертывания с помощью

HHH000231: экспорт схемы завершился неудачно: java.sql.SQLException: вы не можете установить автоматическую фиксацию во время управляемой транзакции!

Это нормально, потому что место, куда вводится em, в основномвнутри транзакции.У кого-нибудь есть идея?

Ответы [ 2 ]

2 голосов
/ 06 декабря 2011

Во-первых, я бы не хотел создавать EntityManagerFactory на лету.Я полагаю, вам придется делать это при каждом создании экземпляра DAO (или любого объекта EJB, который вы используете для доступа к вашей базе данных).Если это так, подумайте дважды: создание EntityManagerFactory очень дорого и обычно должно выполняться один раз в жизненном цикле приложения.В качестве альтернативы я бы, вероятно, создал разные DAO для каждой единицы персистентности, перенеся ответственность за использование одного или другого на верхний уровень, так что вы все еще можете положиться на контейнер для создания EntityManager.

При этом в вашем контексте и в предположении, что метод yieldEM () находится в EJB, и вы используете безопасность, управляемую контейнером, вы можете внедрить EJBContext с помощью:

@Resource
EJBContext ejbContext;

Отсюда вы можете получить Principal и создайте свой EntityManager в зависимости от него.

Если какое-либо из предположений недействительно, дайте мне знать и постараюсь обновить мой ответ.

РЕДАКТИРОВАНИЕ:

@Stateless
public class EntityManagerService {

   @Resource
   EJBContext ejbContext;

   @Produces
   public EntityManager produceEM() {

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

   return managerFactory.createEntityManager();

   }
}

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

0 голосов
/ 06 декабря 2011

Не совсем ответ на ваш вопрос, но рассматривали ли вы JPA мультитенантность?AFAIK и Hibernate, и EclipseLink поддерживают его.

...