Apache Cayenne:将固定的和动态提供的 DataMaps 合并到一个 ServerRuntime 中

Apache Cayenne: Merging fixed with dynamically supplied DataMaps into one ServerRuntime

我的应用程序设计包含固定和动态的数据映射以连接到不同的 (Oracle) 数据库 instances/users。为简单起见,我确实将它们分成了两个不同的 Cayenne 项目。

  1. 使用固定的 DataMap 创建 ServerRuntimeBuilder,构建和查询我的客户 table。
  2. 对于每个客户,使用第二个 ServerRuntimeBuilder 加载动态 DataMap 并进行必要的修改(更改名称和默认模式):

    ...
    List<Customer> allCustomers = Customer.allCustomers(this.cayenneRuntime1.newContext());
    for (Customer customer : allCustomers) {
        final String dbPrefix = customer.getDbprefix();
    
        ServerRuntimeBuilder builder = ServerRuntime.builder();
        // load and modify DataMap
        builder.addConfig("ApacheCayenne/Data/cayenne-dynamicDomain.xml");
        builder.addModule(binder -> {
            binder.bind(DataMapLoader.class).to(MyDataMapLoader.class);
            ServerModule.contributeProperties(binder).put("CUSTOMER_PREFIX", dbPrefix);
        });
        ServerRuntime cayenneRuntime2 = builder.build();
        LOG.info("Initialized customer model " + customer + " prefix: " + customer.getDbprefix());
        // TODO Merge with cayenneRuntime1?
    }
    
    
    public class MyDataMapLoader extends XMLDataMapLoader {  
        @Inject
        private RuntimeProperties properties; 
        @Override
        public DataMap load(Resource configurationResource) throws CayenneRuntimeException {
            DataMap map = super.load(configurationResource);
            // Dynamically set name and default schema to map
            String dbPrefix = properties.get("CUSTOMER_PREFIX");
            map.setName(customer1.dbPrefix + "...")
            map.setDefaultSchema(customer1.dbPrefix + "...")
            return map;
        }
    }
    

还有一个自己的 ConfiguredDataSource 实现,负责 JDBC 连接 URL 和凭据。这部分到目前为止工作正常。

我的问题:通过这种设计,我最终为每个客户1 + n 个服务器运行时间。但最后我想要 一个单一的 ServerRuntime

a) 是否可以将这些 ServerRuntimes 与 Cayenne 4.0RC1 功能和未来版本即时合并?

b) 我需要在 cayenne-project library as described . Modify and store every dynamic Project to the filesystem. After processing all my customers, create a final ServerRuntime with all the Cayenne Projects using the described way with an ExecutingMergerContext or with this Merging Multiple Projects 的帮助下阅读动态地图吗?

ServerRuntime runtime = ServerRuntime.builder()
    .addConfig("com/example/cayenne-fixed-project.xml")
    .addConfig("org/foo/cayenne-dynamic-Customer1.xml")
    .addConfig("org/foo/cayenne-dynamic-Customer2.xml")
    .build();

在此先感谢您对我的帮助。

我会启动 runtime1 来获取配置数据,然后创建包含固定和动态映射的 runtime2,以及一个自定义 DataMap 加载器来动态重写名称和架构:

ServerRuntime runtime2 = ServerRuntime.builder()
  .addConfig("com/example/cayenne-fixed-project.xml")
  .addConfig("org/foo/cayenne-dynamic-Customer1.xml")
  .addConfig("org/foo/cayenne-dynamic-Customer2.xml")
  .addModule(..)
  .build();

只是不要忘记在使用完后关闭 runtime1,这样最后您将只有一个运行时。