cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Hugi Thordarson <>
Subject Re: Dynamic mapping
Date Fri, 20 Jan 2017 14:52:13 GMT
Thanks! Now I have something fun to work on during the weekend :)

- hugi

> On 20. jan. 2017, at 14:26, Andrus Adamchik <> wrote:
> Here it is:
> Hides lots of verbosity in Cayenne mapping API. We may port it to Cayenne in the future
releases if we are to pursue the topic of dynamic mapping.
> Andrus
>> On Jan 20, 2017, at 8:24 AM, Hugi Thordarson <> wrote:
>> As someone who uses multiple Cayenne projects in separate jars a lot (I have a project
for db documentation, another one for user management, another one for generic object tagging
etc. etc.) this is quite awesome and I have oodles of use cases. Can you share the code for
the Relationships utility class?
>> Allowing the Modeler to load and handle multiple models simultaneously would also
be very nice, but that’s a whole another story…
>> - hugi
>>> On 20. jan. 2017, at 01:29, Andrus Adamchik <> wrote:
>>> 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

View raw message