Hi there,
just bumped into another weird EOF case. A pretty plain fetch caused a “Cannot determine primary key for entity” exception. The row contains a number of columns whose values makes sense, some null, some non-null, with one exception — the primary key, modelled as an attribute uid, is indeed a null, thus the exception makes a perfect sense.
How can this happen?
=== IllegalArgumentException: Cannot determine primary key for entity DBRecord from row: {... uid = <com.webobjects.foundation.NSKeyValueCoding$Null>; ... } at com.webobjects.eoaccess.EODatabaseChannel._fetchObject(EODatabaseChannel.java:348) ... skipped 2 stack elements at com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecification(EOObjectStoreCoordinator.java:488) at com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4069) at er.extensions.eof.ERXEC.objectsWithFetchSpecification(ERXEC.java:1215) ... skipped 1 stack elements at com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsForSourceGlobalID(EOObjectStoreCoordinator.java:634) at com.webobjects.eocontrol.EOEditingContext.objectsForSourceGlobalID(EOEditingContext.java:3923) at er.extensions.eof.ERXEC.objectsForSourceGlobalID(ERXEC.java:1178) ... skipped 1 stack elements at com.webobjects.eoaccess.EOAccessArrayFaultHandler.completeInitializationOfObject(EOAccessArrayFaultHandler.java:77) at com.webobjects.eocontrol._EOCheapCopyMutableArray.willRead(_EOCheapCopyMutableArray.java:45) at com.webobjects.eocontrol._EOCheapCopyMutableArray.count(_EOCheapCopyMutableArray.java:103) at com.webobjects.foundation.NSArray.isEmpty(NSArray.java:1888) ... ===
Just in case it happens to be important (I believe it is not), the problem happens at row
... =eolist.representedObject.records().isEmpty()?...:...
where records just returns storedValueForKey('records'), self-evidently a fault, which fires to fetch the rows.
Searching the Web, all I've found is this (linked from here), which does not really help :) Truth is, some background threads do run at the moment; they are comparatively plain though and I can't see why they should cause the problem for the R/R thread. All they do is to
1. get their own OSC from the pool, making sure they never get the same OSC normal sessions have 2. create a new ERXEC in this OSC 3. get a local instance of an object in the EC
=== this is the code of the background thread; a number of those runs: def store for (def pool=ERXObjectStoreCoordinatorPool._pool();;) { store=pool.nextObjectStore if (store!=_sessionosc) break // there's one OSC for all sessions, stored in _sessionosc } return eo.localInstanceIn(ERXEC.newEditingContext(store)).numberOfMasterRowsWithoutOwner() ===
and the method simply fetches:
=== int numberOfMasterRowsWithoutOwner { def mymasterrow=EOQualifier.qualifierWithQualifierFormat("importObject.dataBlock = %@ AND recordOwner = NULL",[this] as NSA) return ERXEOControlUtilities.objectCountWithQualifier(this.editingContext, 'DBRecord', mymasterrow) } ===
Most time it works properly. Occasionally — rather rarely — the problem above happens. Can you see what am I doing wrong?
Thanks a lot, OC
|