cayenne-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Gentry <>
Subject Re: Exposed FK and redundant mappings
Date Wed, 19 Oct 2011 13:08:43 GMT
Hi Andrus,

I'd go with the quick-fix for now (modeler) and maybe explore a better
solution in the future.  It is better to have them deal with a
safe/working restriction and not have potential errors.  Worst case,
if they want the artistId, they can follow the Artist relationship and
get the ID from there.  They can even add a cover method in

public int getArtistId()
    return getArtist().getId();


On Wed, Oct 19, 2011 at 3:02 AM, Andrus Adamchik <> wrote:
> Just coming of a few months (!) of low intensity debugging of a single problem that looked
as if Cayenne resets a non-null to-one relationship to null. The FK would be not null in the
DB, but all instances of a given object across all DataContexts in a given app would return
null for that one relationship. Turned out this wasn't an obscure race condition, but rather
the following scenario:
> 1. Assume Artist and Painting with painting having to one relationship called "artist",
but also an ObjAttribute called "artistId"
> 2. For an existing Artist you may create a new painting, call "setArtist", but don't
set the "artistId" attribute explicitly.
> 3. Commit - that creates a valid record with non-null PAINTING.ARTIST_ID in the db, but
the object snapshot stored in DataRowStore suddenly has NULL for "ARTIST_ID" key.
> 4. From here all DataContexts that fault this painting from the shared cache will have
NULL "artist" relationship, even though it is not null in the DB.
> The actual behavior during (3 - commit) I think is less deterministic and depends on
the relative order of traversal of entity properties in the ClassDescriptor. So theoretically
there may have been a reverse situation when NULL was saved to the DB, but not-null value
remained in the snapshot. In any event it is extremely confusing.
> If we take a broader look at this problem, it is a case of redundant mapping (something
in the DB layer is mapped multiple times in the object layer). There can be other cases with
yet unknown sets of problems (e.g. multiple ObjRelationships over the same DbRelationship;
flattened relationships, with a matching set of 1-step relationships; etc).
> We only have a single case where redundant mapping is handled correctly and consistently
- exposed PK (meaningful or not) . Even if the exposed PK is generated by Cayenne, we have
a mechanism to update object property. So this is a case when we do it right, and don't compromise
on user choices of mapping scenarios.
> In case of exposed FK we have 2 options - (1) just add a Modeler validation to discourage
this type of mapping (quick and easy) and (2) actually analyze the above and other possible
scenarios when we need to synchronize relationship and attribute and write code to do that.
#2 can be done as a post-commit pass over the objects to sync redundant mappings... Just not
clear which one of the redundant mappings should be used to sync the others...
> Thoughts?

View raw message