2013-07-09 5 views
1

Я использую eclipselink с Oracle в своем проекте.Выбор динамической схемы в eclipselink

Я использую сопоставление, основанное на аннотациях, как показано ниже.

@Entity 
@Table(name="ASSIGNMENT", schema="service") 
public class Assignment implements Serializable { 
... 
} 

У меня разные схемы, соответствующие различным странам. Имена таблиц одинаковы. Требование состоит в том, чтобы выбирать имена схем во время выполнения.

Можно ли достичь этого, используя подход, основанный на аннотациях?

Спасибо.

ответ

0

Я предполагаю, что ваши схемы имеют не только одинаковые имена таблиц, но и ту же структуру таблицы.

Способ, которым ваше приложение разработано, не очень хорошо. Предположим, что у вас есть таблица 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, и вы получаете соответствующий подкласс соответственно стране.

1

EclipseLink также позволяет схеме быть установлен с помощью tableQualifier,

см, JPA - EclipseLink - How to configure Database Schema name at runtime

Обратите внимание, что createEntityManagerFactory() будет возвращать один и тот же завод для того же имени единицы сохранения, если вы не передать имущество, отличается (например, URL-адрес, пользователь или "" eclipselink.session-name ").

Смежные вопросы