X-CGP-ClamAV-Result: CLEAN X-VirusScanner: Niversoft's CGPClamav Helper v1.22.2a (ClamAV engine v0.102.2) X-Junk-Score: 0 [] X-KAS-Score: 0 [] From: "Samuel Pelletier" Received: from fortimail.cybercat.ca ([216.13.210.77] verified) by post.selbstdenker.com (CommuniGate Pro SMTP 6.3.3) with ESMTPS id 26008741 for webobjects-dev@wocommunity.org; Fri, 11 Jun 2021 23:35:45 +0200 Received-SPF: none receiver=post.selbstdenker.com; client-ip=216.13.210.77; envelope-from=samuel@samkar.com Received: from smtpclient.apple (modemcable213.203-171.107.mc.videotron.ca [107.171.203.213]) (user=samuel%samkar.com mech=PLAIN bits=0) by fortimail.cybercat.ca with ESMTP id 15BLZNwf012598-15BLZNwg012598 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 11 Jun 2021 17:35:24 -0400 Content-Type: multipart/alternative; boundary="Apple-Mail=_7EAD422F-01F8-48CF-8F9A-67EE7A38582D" Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.100.0.2.22\)) Subject: Re: [WO-DEV] Cannot determine primary key for entity Date: Fri, 11 Jun 2021 17:35:22 -0400 References: To: WebObjects & WOnder Development In-Reply-To: Message-Id: <8A1E47D4-ACE8-4F95-A311-8AAEC73A7325@samkar.com> X-Mailer: Apple Mail (2.3654.100.0.2.22) X-FEAS-AUTH-USER: samuel%samkar.com --Apple-Mail=_7EAD422F-01F8-48CF-8F9A-67EE7A38582D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi, First thing to check is your data. Is the "uid" column has a non null or = primary key constraint ? If no, you probably are fetching a row with a null value. This exception = occur in pretty low level code, before EOF snapshots cache when trying = to construct a global id. If there is a constraint, can you indicate the database column type and = model type used ? Regards, Samuel > Le 11 juin 2021 =C3=A0 07:37, OCsite = a =C3=A9crit : >=20 > Hi there, >=20 > just bumped into another weird EOF case. A pretty plain fetch caused a = =E2=80=9CCannot determine primary key for entity=E2=80=9D exception. The = row contains a number of columns whose values makes sense, some null, = some non-null, with one exception =E2=80=94 the primary key, modelled as = an attribute uid, is indeed a null, thus the exception makes a perfect = sense. >=20 > How can this happen? >=20 > =3D=3D=3D > IllegalArgumentException: Cannot determine primary key for entity = DBRecord from row: {... uid =3D = ; ... } > at = com.webobjects.eoaccess.EODatabaseChannel._fetchObject(EODatabaseChannel.j= ava:348) > ... skipped 2 stack elements > at = com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecific= ation(EOObjectStoreCoordinator.java:488) > at = com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EO= EditingContext.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(EOEditi= ngContext.java:3923) > at er.extensions.eof.ERXEC.objectsForSourceGlobalID(ERXEC.java:1178) > ... skipped 1 stack elements > at = com.webobjects.eoaccess.EOAccessArrayFaultHandler.completeInitializationOf= Object(EOAccessArrayFaultHandler.java:77) > at = com.webobjects.eocontrol._EOCheapCopyMutableArray.willRead(_EOCheapCopyMut= ableArray.java:45) > at = com.webobjects.eocontrol._EOCheapCopyMutableArray.count(_EOCheapCopyMutabl= eArray.java:103) > at com.webobjects.foundation.NSArray.isEmpty(NSArray.java:1888) > ... > =3D=3D=3D >=20 > Just in case it happens to be important (I believe it is not), the = problem happens at row >=20 > ... =3Deolist.representedObject.records().isEmpty()?...:... >=20 > where records just returns storedValueForKey('records'), = self-evidently a fault, which fires to fetch the rows. >=20 > 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 >=20 > 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 >=20 > =3D=3D=3D this is the code of the background thread; a number of those = runs: > def store > for (def pool=3DERXObjectStoreCoordinatorPool._pool();;) { > store=3Dpool.nextObjectStore > if (store!=3D_sessionosc) break // there's one OSC for all = sessions, stored in _sessionosc > } > return = eo.localInstanceIn(ERXEC.newEditingContext(store)).numberOfMasterRowsWitho= utOwner() > =3D=3D=3D >=20 > and the method simply fetches: >=20 > =3D=3D=3D > int numberOfMasterRowsWithoutOwner { > def = mymasterrow=3DEOQualifier.qualifierWithQualifierFormat("importObject.dataB= lock =3D %@ AND recordOwner =3D NULL",[this] as NSA) > return = ERXEOControlUtilities.objectCountWithQualifier(this.editingContext, = 'DBRecord', mymasterrow) > } > =3D=3D=3D >=20 > Most time it works properly. Occasionally =E2=80=94 rather rarely =E2=80= =94 the problem above happens. Can you see what am I doing wrong? >=20 > Thanks a lot, > OC >=20 >=20 --Apple-Mail=_7EAD422F-01F8-48CF-8F9A-67EE7A38582D Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 Hi,

First = thing to check is your data. Is the "uid" column has a non null or = primary key constraint ?

If no, you probably are fetching a row with a null value. = This exception occur in pretty low level code, before EOF snapshots = cache when trying to construct a global id.

If there is a constraint, can you = indicate the database column type and model type used ?

Regards,

Samuel


Le 11 juin 2021 =C3=A0 07:37, OCsite <webobjects-dev@wocommunity.org> a =C3=A9crit = :

Hi = there,

just = bumped into another weird EOF case. A pretty plain fetch caused a = =E2=80=9CCannot determine primary key for entity=E2=80=9D exception. The = row contains a number of columns whose values makes sense, some null, = some non-null, with one exception =E2=80=94 the primary key, modelled as = an attribute uid, is indeed a null, thus the exception makes a perfect = sense.

How can this = happen?

=3D=3D=3D
IllegalArgumentException: = Cannot determine primary key for entity DBRecord from row: {... uid =3D = <com.webobjects.foundation.NSKeyValueCoding$Null>; ... = }
  at = com.webobjects.eoaccess.EODatabaseChannel._fetchObject(EODatabaseChannel.j= ava:348)
    =  ... skipped 2 stack elements
  at = com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecific= ation(EOObjectStoreCoordinator.java:488)
  at = com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EO= EditingContext.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(EOEditi= ngContext.java:3923)
  at = er.extensions.eof.ERXEC.objectsForSourceGlobalID(ERXEC.java:1178)
     ... skipped = 1 stack elements
  at = com.webobjects.eoaccess.EOAccessArrayFaultHandler.completeInitializationOf= Object(EOAccessArrayFaultHandler.java:77)
  at = com.webobjects.eocontrol._EOCheapCopyMutableArray.willRead(_EOCheapCopyMut= ableArray.java:45)
  at = com.webobjects.eocontrol._EOCheapCopyMutableArray.count(_EOCheapCopyMutabl= eArray.java:103)
  at = com.webobjects.foundation.NSArray.isEmpty(NSArray.java:1888)=
...
=3D=3D=3D

Just in case it happens to be important (I = believe it is not), the problem happens at row

  =       ... = =3Deolist.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

=3D=3D=3D this is the code of the = background thread; a number of those runs:
        def store
    =     for = (def = pool=3DERXObjectStoreCoordinatorPool._pool();;) {
            = store=3Dpool.nextObjectStore
        =     if (store!=3D_sessionosc) = break // there's one OSC for all sessions, = stored in _sessionosc
      =   }
      =   return eo.localInstanceIn(ERXEC.newEditingContext(s= tore)).numberOfMasterRowsWithoutOwner()
=3D=3D=3D

and the method simply = fetches:

=3D=3D=3D
  =   int = numberOfMasterRowsWithoutOwner {
      =   def = mymasterrow=3DEOQualifier.qualifierWithQualifierFormat("importObject.dataBlock =3D = %@ AND recordOwner =3D NULL",[this] as NSA)
        return ERXEOControlUtilities.objectCountWithQualifier(this.editingContext, 'DBRecord', mymasterrow)
    }
=3D=3D=3D

Most time it works = properly. Occasionally =E2=80=94 rather rarely =E2=80=94 the problem = above happens. Can you see what am I doing wrong?
Thanks a lot,
OC



= --Apple-Mail=_7EAD422F-01F8-48CF-8F9A-67EE7A38582D--