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 - 12:52:35 EDT