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 14:48:50 GMT
Hi Richard,

That's similar to what I was suggesting, but it sounds like you ran
into a problem first.  That's why I was saying just prevent it in the
Modeler and we can document how to work around it.



On Wed, Oct 19, 2011 at 10:28 AM, Richard Frovarp <> wrote:
> On 10/19/2011 02: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?
> I've ran into the problem myself when using non-synthetic keys. A warning in
> the modeler would be useful, but I wouldn't prohibit the behavior. The work
> around for my code was something like this:
> public class Painting {
>  @Override
>  public void setArtist(Artist artist) {
>    super.setArtist(artist);
>    this.setArtistId(artist.getId());
>  }
> }

View raw message