Jpa eclipselink中的动态模式选择

Jpa eclipselink中的动态模式选择,jpa,annotations,eclipselink,database-schema,Jpa,Annotations,Eclipselink,Database Schema,在我的项目中,我将eclipselink与Oracle一起使用 我正在使用基于注释的映射,如下所示 @Entity @Table(name="ASSIGNMENT", schema="service") public class Assignment implements Serializable { ... } 我有不同的模式对应不同的国家。表名是相同的。要求是在运行时选择模式名称 使用基于注释的方法是否可以实现这一点 谢谢。我假设您的模式不仅具有相同的表名,而且具有相同的表结构 应用程序的

在我的项目中,我将eclipselink与Oracle一起使用

我正在使用基于注释的映射,如下所示

@Entity
@Table(name="ASSIGNMENT", schema="service")
public class Assignment implements Serializable {
...
}
我有不同的模式对应不同的国家。表名是相同的。要求是在运行时选择模式名称

使用基于注释的方法是否可以实现这一点


谢谢。

我假设您的模式不仅具有相同的表名,而且具有相同的表结构

应用程序的设计方式不好。假设在模式“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);
诀窍就在地图上。从中复制和改编一些代码,您可以执行以下操作:

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);
    }
}
import static org.eclipse.persistence.config.PersistenceUnitProperties.*;
...
公共最终类连接器{
私有静态最终地图因子按国家/地区=
新的HashMap();
专用连接器(){}
公共静态同步EntityManagerFactory getEntityManagerFactory(国家/地区){
EntityManagerFactory emf=factoriesByCountry.get(国家);
if(emf==null){
emf=createEntityManagerFactory(国家/地区);
factoriesByCountry.put(国家,emf);
}
返回电动势;
}
私有静态EntityManagerFactory createEntityManagerFactory(国家/地区){
映射属性=新的HashMap();
//确保使用本地事务的资源。
properties.put(事务类型),
PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
//配置内部EclipseLink连接池。
//TODO:根据给定的国家/地区对您的连接和模式进行个性化设置。
put(JDBC_驱动程序,“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());
//配置日志记录。FINE确保显示所有SQL
属性。put(记录_级,“罚款”);
put(LOGGING_TIMESTAMP,“false”);
put(LOGGING_THREAD,“false”);
put(LOGGING_SESSION,“false”);
//确保未配置任何服务器平台
properties.put(TARGET_SERVER,TargetServer.None);
//现在可以实例化EntityManagerFactory:
返回Persistence.createEntityManagerFactory(country.getUnitName(),properties);
}
}
如果您使用的是JavaEE,那么它将在很大程度上取决于您的容器,但是您需要执行与上面类似的操作

显然,在创建
EntityManager工厂之后,您需要获取
EntityManager
,可能需要在那里传递一些其他属性。此外,您需要在任何地方跟踪正确的
国家/地区。您甚至可以通过使用多个
EntityManagerFactory
连接到多个数据库,尽管不混合和混淆来自不同国家/地区的托管实体可能很棘手,因此我建议您将此信息添加到每个实体类中以帮助您


如果您的表结构在不同的国家不同,那么您的实体类将需要了解这一点。在这种情况下,一个可能的解决方案是定义
Assignment
FranceAssignment
SpainAssignment
的超类,然后根据国家获得正确的子类。

我假设您的模式不仅具有相同的表名,而且具有相同的表结构

应用程序的设计方式不好。假设在模式“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);
诀窍就在地图上。从中复制和改编一些代码,您可以执行以下操作:

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);
    }
}
import static org.eclipse.persistence.config.PersistenceUnitProperties.*;
...
公共最终类连接器{
私有静态最终地图因子按国家/地区=
新的HashMap();
专用连接器(){}
公共静态同步EntityManagerFactory getEntityManagerFactory(国家/地区){
EntityManagerFactory emf=factoriesByCountry.get(国家);
if(emf==null){
emf=createEntityManagerFactory(国家/地区);
factoriesByCountry.put(国家,emf);
}
返回电动势;
}
私有静态EntityManagerFactory createEntityManagerFactory(国家/地区){
映射属性=新的HashMap();
//确保使用本地事务的资源。
properties.put(事务类型),
PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
//配置内部EclipseLink连接池。
//TODO:根据给定的国家/地区对您的连接和模式进行个性化设置。
properties.put(JDBC_驱动程序)或