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

Reply via email to