Я предполагаю, что ваши схемы имеют не только одинаковые имена таблиц, но и ту же структуру таблицы.
Способ, которым ваше приложение разработано, не очень хорошо. Предположим, что у вас есть таблица ASSIGNMENT в схемах «france» и «spain». Это явно плохое дизайнерское решение, так как было бы гораздо лучше иметь колонку, описывающую страну. Поэтому неудивительно, что JPA не совсем подходит для этой функции.
Кроме того, вы все еще можете справиться с этой ситуацией с JPA. Вам нужно будет посмотреть на EntityManagerFactory
. Если вы используете JavaSE специально искать для этого метода в классе javax.persistence.Persistence
:
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties);
И для этого метода в интерфейсе javax.persistence.EntityManagerFactory
:
public EntityManager createEntityManager(Map properties);
Хитрость заключается в карте. Копирование и адаптация код из this page, вы могли бы сделать что-то вроде этого:
import static org.eclipse.persistence.config.PersistenceUnitProperties.*;
...
public final class Connector {
private static final Map<Country, EntityManagerFactory> factoriesByCountry =
new HashMap<>();
private Connector() {}
public static synchronized EntityManagerFactory getEntityManagerFactory(Country country) {
EntityManagerFactory emf = factoriesByCountry.get(country);
if (emf == null) {
emf = createEntityManagerFactory(country);
factoriesByCountry.put(country, emf);
}
return emf;
}
private static EntityManagerFactory createEntityManagerFactory(Country country) {
Map<Object, Object> properties = new HashMap<>();
// Ensure RESOURCE_LOCAL transactions is used.
properties.put(TRANSACTION_TYPE,
PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
// Configure the internal EclipseLink connection pool.
// TODO: Personalize your connection and schema accordingly to the given Country.
properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
properties.put(JDBC_URL,
"jdbc:oracle:thin:@" + country.getHost() + ":1521:" + country.getSchema());
properties.put(JDBC_USER, country.getUser());
properties.put(JDBC_PASSWORD, country.getPassword());
// Configure logging. FINE ensures all SQL is shown
properties.put(LOGGING_LEVEL, "FINE");
properties.put(LOGGING_TIMESTAMP, "false");
properties.put(LOGGING_THREAD, "false");
properties.put(LOGGING_SESSION, "false");
// Ensure that no server-platform is configured
properties.put(TARGET_SERVER, TargetServer.None);
// Now the EntityManagerFactory can be instantiated:
return Persistence.createEntityManagerFactory(country.getUnitName(), properties);
}
}
Если вы используете JavaEE, то он будет сильно зависеть от вашего контейнера, но вам нужно будет сделать что-то подобное описанному выше.
И, очевидно, после создания EntityManagerFactory
вам нужно будет получить EntityManager
, возможно, передав некоторые другие объекты. Кроме того, вам нужно будет отслеживать правильные Country
везде. Вы можете даже подключиться к нескольким базам данных, используя несколько EntityManagerFactories
, хотя было бы сложно не смешивать и путать управляемые объекты из разных стран, поэтому я предлагаю вам добавить эту информацию в каждый класс сущности, чтобы помочь вам.
Если структура вашей таблицы отличается от страны, то вам придется выяснить, что у вас есть классы объектов. В этом случае возможным решением является определение того, что Assignment
является суперклассом как FranceAssignment
, так и SpainAssignment
, и вы получаете соответствующий подкласс соответственно стране.