Как мне подключиться к нескольким базам данных с помощью JPA? - PullRequest
19 голосов
/ 22 февраля 2010

У меня есть приложение, использующее сервлеты Java / JSP. Множество клиентов используют мое приложение, однако у каждого клиента есть отдельная база данных. Все базы данных имеют одинаковую схему. Я хотел бы определить, какое соединение с базой данных использовать во время входа пользователя в систему.

Например, клиент A входит в систему, я определяю, что клиент A принадлежит базе данных C, получаю соединение с базой данных C и продолжаю в том же духе.

Я использую JPA с Hibernate в качестве поставщика JPA. Можно ли сделать это, используя несколько единиц персистентности и определить, какую единицу использовать во время входа в систему? Есть ли лучший / предпочтительный способ сделать это?

Отредактировано, чтобы добавить: Я использую аннотации и EJB, поэтому контекст постоянства устанавливается в EJB с помощью @PersistenceContext (unitName = "blahblah"), это можно определить во время входа? Могу ли я изменить unitName во время выполнения?

Спасибо

1 Ответ

19 голосов
/ 22 февраля 2010

1) Создайте несколько постоянных единиц в вашем persistence.xml с разными именами.

2) Создайте необходимое число EntityManagerFactory с (1 на единицу персистентности) и укажите, какую единицу постоянства следует использовать для бетонного завода:

<bean id="authEntityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
   <property name="persistenceUnitName" value="SpringSecurityManager"/>
</bean>

3) Создайте необходимое количество TransactionManager с:

<bean id="authTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="authEntityManagerFactory" />
</bean>

4) В ваших классах DAO укажите, с каким постоянным модулем (и, следовательно, с каким EntityManagerFactory) вы хотите работать:

public class AbstractAuthDao<T> { 

   @PersistenceContext (unitName = "SpringSecurityManager")
   protected EntityManager em;

    ...
}

5) В ваших сервис-объектах укажите, какой TransactionManager следует использовать (эта функция поддерживается только в Spring 3.0):

@Transactional (value = "authTransactionManager", readOnly = true)
public class UserServiceImpl implements UserService {

   ...
}

6) Если у вас есть OpenEntityManagerInViewFilter в вашем web.xml, то укажите в его init-param имя необходимого EntityManagerFactory (или создайте несколько фильтров с соответствующими init-блоками):

<init-param>
    <param-name>entityManagerFactoryBeanName</param-name>
    <param-value>authEntityManagerFactory</param-value>
</init-param>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...