cayenne-user mailing list archives

TL;DR: Map relationships dynamically in a running app if you need to connect multiple reusable
ORM modules.
A longer version:
I'd often mention at various presentations that Cayenne supports generic objects and you can
create mapping in runtime. I didn't have many real-life examples to demonstrate the need until
now. But recently I encountered a good use case that was solved by dynamic mapping - reusable
ORM modules.
Say I have a reusable lib.jar containing a Cayenne project and some persistent code built
around it. Now I want to use it in app.jar (or app.war if you are still on JavaEE). app.jar
has its own Cayenne project, with entities that need to reference entities in lib.jar. You
can't relate them in the Modeler, short of unpacking lib.jar and reassembling a new project
from both projects (the level of effort with such approach would kill most of the benefits
of reuse).
Consider that in runtime EntityResolver would contain entities from both lib and app, so all
we need is to connect them. So instead of messing with XML files, we'd create a DataChannelFilter
in app.jar with "init" method that builds all needed relationships on the fly. Now we can
access these relationships via generic DataObject API (on the app.jar side you can optionally
create regular type-safe getters and setters). I wrote a utility relationship builder that
makes this code transparent:
Relationships.oneToOne("libEntity")
.between(AppEntity.class, LibEntity.class)
.toDepPK()
.joined(AppEntity.ID_PK_COLUMN, LibEntity.ID_PK_COLUMN)
.createReverse("appEntity")
.exec(resolver);
Needless to say that all this happens in a running application, and is not limited to relationships.
E.g. you can create flattened attributes instead.
The implications are pretty exciting - you can write fully self-contained libraries with Cayenne
that can be easily extended (without unpacking) with more tables, and otherwise integrated
in app DB schemas. Dynamic mapping was the last missing piece of a puzzle in a modular CMS
design that I am working on right now. Ironically the feature was there in Cayenne since Day
1, waiting to get noticed.
Andrus
---------------
Andrus Adamchik
@andrus_a | @ApacheCayenne