Chuck, > On 20. 9. 2016, at 10:48 PM, Chuck Hill <ch...@gevityinc.com> wrote: > > This is why they are getting inserted again: > Well, logging out > "currentUser.editingContext().committedSnapshotForObject(currentUser)['userDataBlock']" > before saveChanges, I get an empty array. I must admit I don't know whether > there should be the relationship objects in this snapshot, but anyway: > > It should not be an empty array. EOF compares this and the relationship on > the EO to determine what database operations are needed.
I see. > I’d start with logging that out just after you fetch/fault currentUser into > ec (you don’t show that below). If it is empty there, then keep logging to > see where the data disappears. At this point, I am not ready to guess. The thing seems empty all the time. Weird. Here's what I log fetch-time: === def cbc=.... // the business case whose users are about to be fetched println "### about to fetch $cbc...\noldSS ${cbc.editingContext().committedSnapshotForObject(cbc).userDataBlocks}" def xxx=cbc.userDataBlocks() println "### -> did fetch $xxx\nnewSS ${cbc.editingContext().committedSnapshotForObject(cbc).userDataBlocks}" xxx.each { println "### user $it\n### rel ${it.dataBlockUsers()}\n### ss ${it.editingContext().committedSnapshotForObject(it).dataBlockUsers}" } === Presumably, the “oldSS” should be empty, but the “newSS” should be a copy of the relationship value (i.e., “cbc.userDataBlocks()”, or “xxx”)? It is not; the snapshot consistently stays empty: === ### about to fetch <DBDataBlock@d6ff2f9 PK:1000003 Title:'überblok' /EC:6350cea5>... oldSS [] ### -> did fetch [<DBUser@6f400a99 PK:1000005 T:'3' Name:'cl' /EC:6350cea5>, <DBUser@5f8a5755 PK:1000006 T:'3' Name:'c2' /EC:6350cea5>, <DBUser@569a703e PK:1000009 T:'4' Name:'kl kl kl' /EC:6350cea5>] newSS [] === Aside of that, I have added a log into the DatabaseContextDelegate.databaseContextShouldUpdateCurrentSnapshot method, and here I *never* get *anything* for the relationships: neither the old (which is presumable) *nor the new* dictionary ever contain the “userDataBlocks” or “dataBlockUsers” key — not once. Well it still might be a wrong model settings as Samuel suggests perhaps? But it is sort of weird I use this settings for years and lots of M:N's, and this is the first time I have bumped into this kind of problems. Can you see what to check next? Thanks a very big lot, OC > > Also, this is 100% consistent, right? This is not a concurrency issue? > > Chuck > > > From: <webobjects-dev-bounces+chill=gevityinc....@lists.apple.com> on behalf > of "o...@ocs.cz" <o...@ocs.cz> > Date: Tuesday, September 20, 2016 at 11:50 AM > To: "webobjects-dev@lists.apple.com WebObjects" > <webobjects-dev@lists.apple.com> > Subject: EOF inserts already existing M:N relationships/empty snapshot?!? > > Hello there, > > I have a pretty common setup: entities User and DataBlock, an M:N > relationship represented by an intermediate entity containing just the two > keys, flattened on both sides. At both sides the relationships are > appropriately flattened. Set to own destination+delete rule cascade. > > The problem is, upon inserting a new DataBlock and its relationship to a > current user, beside the two objects which should be inserted (the new > DataBlock and the new relationship), relationships to other (old) DataBlocks, > which were before simply _fetched_ for the current user (just to display the > current state), get inserted too — which, of course, causes an integrity > constraint violation “this PK already exists“. > > My code looks essentially like this: > > === > EOEditingContext ec= ... > DBDataBlock ndb=new DBDataBlock() > ec.insertObject(ndb) > ndb.addObjectToBothSidesOfRelationshipWithKey(currentUser,'dataBlockUsers') > // logs here, see below > ec.saveChanges() > === > > Immediately before ec.saveChanges(), I log out > > (a) ec.insertedObjects(), which contains only one object (I have overridden > toString() to get the PK /and other attributes, removed here for conciseness/ > of an EO): > > [<DBDataBlock@79adaefa PK:null>] > > this is all right, null PK means a newly added object, it's the very 'ndb' > datablock I just have inserted and which I am now saving. > > (b) contents of the flattened M:N relationship 'ndb.dataBlockUsers' from the > DBDataBlock@79adaefa to DBUser, which looks like this: > > [<DBUser@71b29988 PK:1000005>] > > again, quite all right: only one related user, the currentUser which I have > just added to the relationship. > > (c) contents of the flattened M:N inverse relationship from the current user, > which looks like this: > > [<DBDataBlock@189f083a PK:1000003>, <DBDataBlock@1b47d247 PK:1000016>, > <DBDataBlock@5f927095 PK:1000019>, <DBDataBlock@54edfe4c PK:1000022>, > <DBDataBlock@35e1e59c PK:1000023>, <DBDataBlock@793b3d6d PK:1000024>, > <DBDataBlock@7b06dee8 PK:1000029>, <DBDataBlock@2550aab9 PK:1000033>, > <DBDataBlock@79adaefa PK:null>] > > for the third time, all right: 8 of them previously fetched, already existing > relationships to other (old) datablocks for the current user, plus one new > relationship to the newly added DBDataBlock@79adaefa. Perfect so far. > > At this moment, ec.saveChanges is performed. I log the database operations > from databaseContextWillPerformAdaptorOperations delegate method, and it > looks like this: > > === > -IN-adaptorOps === SPC: about to perform 10 DB operations |19:54:37.061 > 20.9.16|WorkerThread1 > - 1: INSERT on 'DBDataBlock' 1{uid:1000042} > - 2: INSERT on 'DB_UserDataBlock' 2{db_id:1000023, > user_id:1000005} > - 3: INSERT on 'DB_UserDataBlock' 2{db_id:1000022, > user_id:1000005} > - 4: INSERT on 'DB_UserDataBlock' 2{db_id:1000003, > user_id:1000005} > - 5: INSERT on 'DB_UserDataBlock' 2{db_id:1000016, > user_id:1000005} > - 6: INSERT on 'DB_UserDataBlock' 2{db_id:1000042, > user_id:1000005} > - 7: INSERT on 'DB_UserDataBlock' 2{db_id:1000019, > user_id:1000005} > - 8: INSERT on 'DB_UserDataBlock' 2{db_id:1000029, > user_id:1000005} > - 9: INSERT on 'DB_UserDataBlock' 2{db_id:1000024, > user_id:1000005} > - 10: INSERT on 'DB_UserDataBlock' 2{db_id:1000033, > user_id:1000005} > === > > i.e., along with inserting the two new objects (1: the new datablock, 6: the > new relationship), EOF for some darned reason decides to insert _also_ all > those relationship objects it _fetched_ before! Of course, since they were > fetched, they already exist in the database, and thus cause an integrity > constraint violation “this PK already exists“. > > Well, logging out > "currentUser.editingContext().committedSnapshotForObject(currentUser)['userDataBlock']" > before saveChanges, I get an empty array. I must admit I don't know whether > there should be the relationship objects in this snapshot, but anyway: > > - if not, I have no idea where to find the culprit; > - if yes, well, the culprit of those inserts is explained, but why on earth > the snapshot is not properly maintained by EOF?!? > > Any idea what might be the culprit, or at least, how to find it? I am afraid > I am rather out of ideas :/ > > Thanks a lot, > OC > > > _______________________________________________ > Do not post admin requests to the list. They will be ignored. > Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/webobjects-dev/chill%40gevityinc.com > > This email sent to ch...@gevityinc.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com