Я боролся с этой проблемой в течение нескольких дней,Управление несколькими базами данных Соединения
Вот сценарий: У меня есть несколько баз данных, один для каждого из моих клиентов, все с той же структуры (то же самое таблицы и столбцы), поэтому мое приложение должно решить во время выполнения, с которым ему нужно подключиться. Я использую JPA2, EclipseLink и EJB3.
Моя первая попытка состояла в том, чтобы реализовать пользовательский EntityManager со всей логикой для выполнения операций с правой базой данных, затем я сконфигурировал этот EntityManager как EBate без учета состояния, чтобы сделать возможным его добавление с помощью аннотации @EBJ (как описано по этой ссылке: http://www.hostettler.net/blog/2012/11/20/multi-tenancy/). Я не заставляю его работать, потому что он бросает исключение, пытаясь внедрить EntityManager.
Так что я решил попробовать что-то другое, я создал EntityManagerFactory и я передал JTA_DATASOURCE к нему (после того, как решить, во время выполнения, один для использования), поэтому он может подключиться к базе данных правой .
Вот код:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestEntDAO {
private EntityManager em;
private EntityManagerFactory emf;
@PostConstruct
public void init() {
em = getEntityManager();
}
public EntityManager getEntityManager() {
Map props = new HashMap();
props.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
props.put(PersistenceUnitProperties.JTA_DATASOURCE, dataSourceName());
emf = Persistence.createEntityManagerFactory("testePU", props);
em = emf.createEntityManager();
return em;
}
public String dataSourceName(){
if(someCondition){
return "db1";
}else{
return "db2";
}
}
}
Это работало отлично, единственная проблема заключается в том, что сделка не управляется контейнера, так что я должен был явно отметить границы сделки (называют начать() и commit()). Я мог бы просто использовать аннотацию @PersistenceContext, чтобы она работала, но тогда у меня не было бы EntityManagerFactory для передачи источника данных.
Кто-нибудь знает, как использовать Транзакции, управляемые контейнером (CMT), и все еще иметь возможность передавать данные?
Почему вы не можете вводить имя источника данных? Или прочитать его из файла свойств? –
Я просто не мог найти способ сделать это и использовать @PersistenceContext в то же время –