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