Return-Path: X-Original-To: apmail-cayenne-dev-archive@www.apache.org Delivered-To: apmail-cayenne-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D0DE19E3B for ; Wed, 19 Oct 2011 13:09:30 +0000 (UTC) Received: (qmail 48849 invoked by uid 500); 19 Oct 2011 13:09:30 -0000 Delivered-To: apmail-cayenne-dev-archive@cayenne.apache.org Received: (qmail 48808 invoked by uid 500); 19 Oct 2011 13:09:30 -0000 Mailing-List: contact dev-help@cayenne.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cayenne.apache.org Delivered-To: mailing list dev@cayenne.apache.org Received: (qmail 48800 invoked by uid 99); 19 Oct 2011 13:09:30 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Oct 2011 13:09:30 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [209.85.161.171] (HELO mail-gx0-f171.google.com) (209.85.161.171) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Oct 2011 13:09:25 +0000 Received: by ggnv5 with SMTP id v5so2323689ggn.16 for ; Wed, 19 Oct 2011 06:09:03 -0700 (PDT) Received: by 10.147.29.24 with SMTP id g24mr1436936yaj.24.1319029743297; Wed, 19 Oct 2011 06:09:03 -0700 (PDT) MIME-Version: 1.0 Received: by 10.147.169.12 with HTTP; Wed, 19 Oct 2011 06:08:43 -0700 (PDT) In-Reply-To: References: From: Michael Gentry Date: Wed, 19 Oct 2011 09:08:43 -0400 Message-ID: Subject: Re: Exposed FK and redundant mappings To: dev@cayenne.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 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 Painting.java: public int getArtistId() { return getArtist().getId(); } mrg On Wed, Oct 19, 2011 at 3:02 AM, Andrus Adamchik w= rote: > Just coming of a few months (!) of low intensity debugging of a single pr= oblem that looked as if Cayenne resets a non-null to-one relationship to nu= ll. 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 rela= tionship. 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 ca= lled "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 ca= che 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 Cla= ssDescriptor. 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 mapp= ing (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. multipl= e ObjRelationships over the same DbRelationship; flattened relationships, w= ith a matching set of 1-step relationships; etc). > > We only have a single case where redundant mapping is handled correctly a= nd consistently - exposed PK (meaningful or not) . Even if the exposed PK i= s generated by Cayenne, we have a mechanism to update object property. So t= his 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 validati= on to discourage this type of mapping (quick and easy) and (2) actually ana= lyze the above and other possible scenarios when we need to synchronize rel= ationship 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?