Cayenne 3.1 - setting datasource dynamically

梦想与她 提交于 2019-12-01 07:55:23

问题


I'm using Cayenne 3.1B2 at present as the persistence layer for some web services. There's a requirement for the services to expose one of several databases, all with the same schema, the database being determined when the service operation is invoked. The decision on which database is used needs to be based on the identity of the client invoking the service.

How would I go about defining this and using it at runtime? It seems like I should define 2 datanodes, both referring to the same datamap since all my entities are the same between databases.

But at runtime, would I then somehow create two different Contexts, one for each datanode, and if so how would I specify that for each Context?

Any help is appreciated Thanks


回答1:


I would create a single project with a DataMap and single DataNode. Delete its "DataSource Factory" as we'd be specifying it in the code (never tried this, if leaving "DataSource Factory" empty causes any problems on startup, you can set it to any of the provided choices, e.g. JNDIDataSourceFactory, with an understanding that this is just placeholder and will be ignored in runtime).

Now start your 2 ServerRuntimes, each using the same single mapping project, but 2 distinct sets of properties for the DataSource. These properties cause Cayenne to ignore DataSource Factory set in XML.

Module m1 = new Module() {

    @Override
    public void configure(Binder binder) {
        binder.bindMap(Constants.PROPERTIES_MAP)
              .put(Constants.JDBC_DRIVER_PROPERTY, "com.my.Driver")
              .put(Constants.JDBC_URL_PROPERTY, "jdbc://db1_url")
              .put(Constants.JDBC_USERNAME_PROPERTY, "db1login")
              .put(Constants.JDBC_PASSWORD_PROPERTY, "db1password");
    }
};

Module m2 = new Module() {

    @Override
    public void configure(Binder binder) {
        binder.bindMap(Constants.PROPERTIES_MAP)
               .put(Constants.JDBC_DRIVER_PROPERTY, "com.my.Driver")
               .put(Constants.JDBC_URL_PROPERTY, "jdbc://db2_url")
               .put(Constants.JDBC_USERNAME_PROPERTY, "db2login")
               .put(Constants.JDBC_PASSWORD_PROPERTY, "db2password");
    }
};

ServerRuntime r1 = new ServerRuntime("cayenne-project.xml", m1);
ServerRuntime r2 = new ServerRuntime("cayenne-project.xml", m2);

r1 and r2 should be application singletons, and you can create ObjectContexts from either one as appropriate for each request. If you are reusing ObjectContexts between requests (e.g. this is a mostly read-only app), you can create 2 contexts from r1 and r2 and also cache them.



来源:https://stackoverflow.com/questions/15506761/cayenne-3-1-setting-datasource-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!