Looks good. I've been using another method that achieves the same
result, or maybe a more limited case of the same result, with a bit less
code.
I have three domain files. The one named cayenne.xml is the one for the
development domain, the one I load in the modeler for all my datamap
editing. The other two files have names like test.cayenne.xml and
prod.cayenne.xml; they differ only in the DataNode.
Cayenne.xml contains:
<domain name="model">
<map name="DataMap" location="DataMap.map.xml"/>
<node name="DataNode"
datasource="DataNode.driver.xml" .../>
<map-ref name="DataMap"/>
</node>
</domain>
Test.cayenne.xml is the same except for one line:
datasource="TestDataNode.driver.xml" .../>
In effect they're sharing a single DataMap as yours do.
My startup code picks the right name to load:
private static synchronized Configuration
getConfiguration(String prefix)
{
Configuration config;
// The prefix is, for example, "test.".
String configName = prefix + "cayenne.xml";
config = new DefaultConfiguration(configName);
Configuration.initializeSharedConfiguration(config);
return config;
}
Gentry, Michael wrote:
> OK, I finally had time to work on this and just got it working and
> thought I'd share in case it helps. I was missing a step, too. I'm
> trying to create a web-based utility application which can access
> different databases, all of which contain the same schema, and the
> different databases need to be accessed at the same time (they only
> share the schema, not the data). I also wanted it simpler to maintain
> (didn't want to copy/paste entity information all over the place).
>
> My model now has 4 DataDomains (one of which is "shared"), each with a
> DataNode pointing to a separate DB. 3 of the DataDomains do *not*
> contain a DataMap (no DB or Java entities), only a DataNode pointing to
> separate DBs. At run-time, I copy the shared DataMap into the
> DB-specific DataDomains. This way, I can create a DataContext,
> specifying the DataDomain I want to use.
>
> In brief:
>
> 1 shared DataDomain which contains 1 shared DataMap with all the DB/Java
> information and 1 DataNode with the shared DataMap under it. I'm not
> even certain I need the DataNode here (haven't tried deleting it yet).
>
> 3 DataDomains, each of which contains 1 DataNode with NO DataMap
> information (at the node or domain level). The DataMap information is
> obtained from the shared DataDomain/Map.
>
> Some Java code to map the shared information to the DB-specific domains:
>
> // This does the "hard" work of mapping the shared model to the domain
> private static void prepareDataDomain(String dataDomainName)
> {
> DataDomain dataDomain =
> Configuration.getSharedConfiguration().getDomain(dataDomainName);
> DataDomain sharedDataDomain =
> Configuration.getSharedConfiguration().getDomain("SharedModel");
>
> // Add the shared map to the data domain
> dataDomain.addMap(sharedDataDomain.getMap("SharedMap"));
>
> // Add the shared map to the data node
> Collection nodes = dataDomain.getDataNodes();
>
> if (nodes.size() != 1)
> {
> System.out.println("Expected only one DataNode for DataDomain '" +
> dataDomainName + "' -- this DataDomain is not usable.");
> return;
> }
>
> Iterator dataNodeIterator = nodes.iterator();
>
> // We are only getting one, though ...
> while (dataNodeIterator.hasNext())
> {
> DataNode node = (DataNode) dataNodeIterator.next();
>
> node.addDataMap(sharedDataDomain.getMap("MCodesSharedMap"));
> }
> }
>
>
> // Setup a domain -- only do this once!
> prepareDataDomain("DomainA");
> prepareDataDomain("DomainB");
> prepareDataDomain("DomainC");
>
>
> // Use a specific domain to get/update data
> DataContext dataContext = DataContext.createDataContext("DomainB");
> ...
> List objects = dataContext.performQuery(someQuery);
>
>
> The DataDomain you specify when you create the DataContext will now
> drive which database the objects are fetched from (and
> inserted/updated/deleted) when you perform your operations.
>
> Hope that can help someone ...
>
> /dev/mrg
>
>
> -----Original Message-----
> From: Gentry, Michael
> Sent: Monday, August 02, 2004 11:04 AM
> To: Todd O'Bryan; cayenne-use..bjectstyle.org
> Subject: RE: Oh, yeah...
>
>
> Funny you should ask that ... I had asked Andrus about that the other
> day. It's a little tricky, but here is the basic idea (note: I haven't
> had time to test this yet, so please let us know if it works):
>
> 1. Create a "shared" DataDomain and DataMap in Cayenne Modeler. This
> will contain your schema definition. You won't need a DataNode here.
>
> 2. Create a DataDomain for each DB you need to access (production and
> test, in your case). You will use these DataDomains later on to suck in
> the shared DataMap you created (step 1).
>
> 3. Underneath each DB-specific DataDomain (step 2), create a DataNode
> with the JDBC connection for each environment's DB. You won't need a
> DataMap here.
>
> 4. At run-time, you'll need to copy the shared DataMap into your
> DB-specific DataDomain. Check out
> Configuration.getSharedConfiguration.getDomain(dataDomainName). Use it
> to get your skeleton DB-specific DataDomain and the shared DataDomain.
> Then use
> skeletonDataDomain.addMap(sharedDataDomain.getMap("MySharedDataMap"))
> which should copy the shared schema into the skeleton one.
>
> That's as far as I've gotten so far. Other things interrupted my
> testing this out. I did have a few funky problems with the modeler, but
> you can work through them. You might also have to remove the shared
> DataMap (see removeMap("MySharedDataMap")) -- not certain, but you'd
> have two maps with entities with the same name otherwise. I hope not,
> because I was looking into making a utility application that could
> access our development/testing/acceptance/production DBs, all at the
> same time within the same web application. Basically, the schema is
> identical, but the connection dictionary differs.
>
> Please let us know how it works for you. If you don't need multiple
> connections, it might be much easier to just change the connection
> dictionary at deployment time.
>
> Thanks,
>
> /dev/mrg
>
>
> -----Original Message-----
> From: Todd O'Bryan [mailto:toddobrya..ac.com]
> Sent: Monday, August 02, 2004 8:59 AM
> To: cayenne-use..bjectstyle.org
> Subject: Oh, yeah...
>
>
> The other part of that question is, is there a way to have the same
> Cayenne configuration file be set up to connect to two different
> databases depending on a parameter, i.e., the production database and
> the test database?
>
> Thanks,
> Todd
>
>
This archive was generated by hypermail 2.0.0 : Wed Sep 08 2004 - 19:42:41 EDT