Spring + Hibernate + JPA + несколько баз данных

У меня есть приложение Spring + Hibernate + JPA. Пользователь при входе в систему может выбрать из списка БД для подключения (это требования). Все БД имеют одинаковую схему, поэтому будут использоваться одни и те же объекты и DAO.

Прямо сейчас у меня есть один EntityManager (на данный момент я работаю с одной базой данных), который вводится в DAO следующим образом:

@PersistenceContext
private EntityManager entityManager;

Есть ли способ, чтобы DAO автоматически получал entityManager (управляемый Spring) на основе параметра / свойства, полученного от уровня сервиса? (Веб-слой отправляет своего рода контекст, и там будет имя / код / ​​идентификатор выбранной базы данных).

Или мне нужно управлять этим сам (создавать все entityManager, помещать их на карту, сообщать DAO, какой из них использовать для каждого вызова)?

Прежде чем задать этот вопрос, я провел небольшое исследование, но результаты оказались неубедительными - большинство вопросов касалось модели, распределенной по 2 или более БД, и транзакций, охватывающих несколько БД, но это не относится ко мне.

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

Спасибо.


person ccc    schedule 02.01.2012    source источник


Ответы (2)


Эта функция называется мультитенантностью.

Hibernate 4 должен поддерживать его прямо из коробки, хотя я не уверен, можно ли его интегрировать с управляемым Spring EntityManager.

В качестве альтернативы, самый простой способ сделать это - перехватить создание подключений к базе данных либо на уровне ConnectionProvider, либо на уровне DataSource и выбрать соответствующую базу данных на основе идентификатора клиента, хранящегося в переменной ThreadLocal.

См. также:

person axtavt    schedule 02.01.2012

Весной вы можете создать EntityManagerFactory динамически с конфигурацией аннотации (AnnotationWebConfiguration), используя что-то вроде этого:

@Configuration
public class MyAppConfig{
   public LocalContainerEntityManagerFactoryBean getEmf(){
       LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean ();
       Datasource ds = new .... ; // HERE!! you can create and configure your datasource to point to whatever you need
       emf.setName("system_pu");
       emf.setDatasource(ds);
       emf.setPackagesToScan(""); //optional if no persistence.xml is defined
       return emf;
   }
}
person Frank Orellana    schedule 06.09.2012