Thanks! Now I have something fun to work on during the weekend :)

- hugi


> On 20. jan. 2017, at 14:26, Andrus Adamchik <and...@objectstyle.org> wrote:
> 
> Here it is:
> 
> https://gist.github.com/andrus/29616d6f20fc5094a4eb77114d751db0
> 
> 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 <h...@karlmenn.is> 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 <and...@objectstyle.org> 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
>>> 
>> 
> 

Reply via email to