2012-01-02 7 views
3

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

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

@PersistenceContext 
private EntityManager entityManager; 

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

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

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

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

Спасибо.

ответ

5

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

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

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

Смотрите также:

1

Весной вы можете построить 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; 
    } 
} 
Смежные вопросы