Chuck, > On 2 Oct 2018, at 8:10 AM, Chuck Hill <ch...@gevityinc.com> wrote: > The other case though is weird. You might recall that my code > - first does some special initialisations without a SEC (all the ECs I use > has their SEC immediately upon creation set to nulls) > - when done, I change the connection dictionary, re-connect using > EODatabaseContext.forceConnectionWithModel, and run on normally with SECs. > > The problem is that during the special init code I happen to need a DBC; and > it seems that the code > > def > ctxt=ERXEOAccessUtilities.databaseContextForEntityNamed(ec.rootObjectStore(),someEntity.name) > > always initialises the default SEC and loads the shared EOs into it — > regardless the fact that the ec does not have a SEC at all. > > I think the author of this may have not quite understood what setting the ec > SEC to null does. It does not prevent SEC creation or loading, it just > affects that particular EC and prevents it from getting/seeing objects in the > SEC. So you can fetch shared objects into it, edit them and save them.
Quite, I see. Nevertheless, it would seem (perhaps mistakenly) to me that the workflow - connect to the database in a special way - initialise without a SEC; this might change objects which normally go to SEC; - re-connect to the database normally - initialise and load and use SEC, as usual is not completely crazy and makes sense? Nevertheless, unless „re-connect“ includes restarting the application, I found no way to achieve that :( > Note that the call to ERXEOAccessUtilities.databaseContextForEntityNamed > does not actually take the EC, it takes the root object store (aka > EOObjectStoreCoordinator in most cases). So that ec.sharedEditingContext() > == null is wholly irrelevant. Quite; but originally, I (definitely mistakenly) though that SEC is initialised and loaded on-demand only when for the first time touched through a normal EC which contain it. Actually, to work around this, I've tried to - go through my model, (store and) remove all the sharedObjectFetchSpecificationNames - connect in a special way, do the initialisation - restore all the sharedObjectFetchSpecificationNames - re-connect etc. Alas, this way, SEC gets never initialised/loaded. > Subsequently, I change (in the EC without a SEC) some shared EOs. The > documentation says that SEC would observe such changes and would refetch > those shared EOs into a SEC; well, it does, but not when they happen, nor > when the EC is saved, nor when it is unlocked — far as I was able to find, it > happens only when the EO in the SEC is touched (i.e., its attribute is read). > > Your apps change the shared Eos when they launch and save them? Every time? > That seems… counter intuitive. My app contains plists which say how (some of) the shared EOs should look like. Upon launching, the special-init-time, it synchronises the database with these plists, so that they really do. Normally, it would mean the shared EOs gets changed only when the application itself (its plists) change, e.g., upon a new release with new features. When testing though, I enforce this change every time, so that I know the synchronisation works properly and am not surprised when deployed and the app changes the next year :) > Without looking, I’d interpret “that SEC would observe such change” as it > will refault the shared objects when it gets the ObjectChangedInObjectStore > notification. So the update to new values would naturally happen when > willRead() is called on a shared EO. There's no problem in that. The problem is that this leads to initializeObject: attempt to initialize object ... error :/ > If this does not happen, i.e., if the previously changed shared EO is not > touched in the SEC, a first fetch into a normal EC (with SEC) whose fetch > spec happens to include a changed shared EO crashes. In other words, it goes > like this: > > (a) init-time, I am consistently using ECs with null SEC; > (b) with one of those, I call databaseContextForEntityNamed, which > initializes and populates the default SEC; > (c) later, in the EC with null SEC, I fetch and change a couple of shared EOs > (they do not get re-loaded in SEC!) > (d) later, normal-run-time, I fetch objects into an EC with SEC; the fetch > spec happens to fit some shared EOs... > > ... and it results in a EOEditingContext: initializeObject: attempt to > initialize object ... that exists in a shared context via a non-shared > context. [1] > > Do the editing contexts from a...c still exist at this time? Probably not. With the Java GC thing one can't be sure; but all of them are stored in local variables of methods which have finished long ago. Hmm... I guess I could make my own EC subclass, override dispose, and log out. Or perhaps I can set log4j.logger.er...something to get that for free? > I have found that the culprit object is one of those changed in the step (c), > and I have found that touching the shared EO in the SEC before the fetch > helps: the shared EO gets re-loaded, and the fetch works as presumed > (returning the shared EO in the SEC). Now, I do this: > > - whenever the SharedEditingContextInitializedObjectsNotification comes, I > record the SEC; > - after the shared EOs are changed (in an EC with null SEC) and saved, I go > through all the SECs recorded; for each of them I get all its > registeredObjects, and for each of them call eo.storedValueForKey(anyKey). If > the object has been changed, this re-loads it in SEC, and subsequent fetching > works properly. > > This seems to me extremely weird. Can you understand what the heck happens > there and why? > > No, not with any certainty. It feels like an EOF bug. Your usage is > probably different from most, so you may be the first to find this. Actually, I feel I must be doing something wrong at my side. Or is really the workflow - do something which inits and loads SEC - load a shared EO into an EC with null SEC, update it, save - in a normal EC (with SEC), do a fetch whose fetchspec fits some shared EOs that unique? That seems surprising. Thanks a lot and all the best, OC > > From: "o...@ocs.cz <mailto:o...@ocs.cz>" <o...@ocs.cz <mailto:o...@ocs.cz>> > Date: Friday, September 28, 2018 at 6:56 PM > To: Chuck Hill <ch...@gevityinc.com <mailto:ch...@gevityinc.com>> > Cc: WebObjects-Dev Mailing List <webobjects-dev@lists.apple.com > <mailto:webobjects-dev@lists.apple.com>> > Subject: Shared EC woes (was: Flattened one-side M:N fails wildly with > SharedEC) > > Chuck, > > well, so far, I have found two problems with SEC. One of them is boringly > self-evident, but a hell to find&fix: very simply, my legacy code did contain > something like > > Foo something() { > ... > > EOUtilities.objectWithPrimaryKeyValue(this.editingContext(),'NonSharedFooEntity',pk) > } > > Which, of course, if this was shared, loads the object into SEC, and hilarity > ensues. I wonder how many similar traps there are in my legacy code... > > The other case though is weird. You might recall that my code > - first does some special initialisations without a SEC (all the ECs I use > has their SEC immediately upon creation set to nulls) > - when done, I change the connection dictionary, re-connect using > EODatabaseContext.forceConnectionWithModel, and run on normally with SECs. > > The problem is that during the special init code I happen to need a DBC; and > it seems that the code > > def > ctxt=ERXEOAccessUtilities.databaseContextForEntityNamed(ec.rootObjectStore(),someEntity.name) > > always initialises the default SEC and loads the shared EOs into it — > regardless the fact that the ec does not have a SEC at all. > > Subsequently, I change (in the EC without a SEC) some shared EOs. The > documentation says that SEC would observe such changes and would refetch > those shared EOs into a SEC; well, it does, but not when they happen, nor > when the EC is saved, nor when it is unlocked — far as I was able to find, it > happens only when the EO in the SEC is touched (i.e., its attribute is read). > > If this does not happen, i.e., if the previously changed shared EO is not > touched in the SEC, a first fetch into a normal EC (with SEC) whose fetch > spec happens to include a changed shared EO crashes. In other words, it goes > like this: > > (a) init-time, I am consistently using ECs with null SEC; > (b) with one of those, I call databaseContextForEntityNamed, which > initializes and populates the default SEC; > (c) later, in the EC with null SEC, I fetch and change a couple of shared EOs > (they do not get re-loaded in SEC!) > (d) later, normal-run-time, I fetch objects into an EC with SEC; the fetch > spec happens to fit some shared EOs... > > ... and it results in a EOEditingContext: initializeObject: attempt to > initialize object ... that exists in a shared context via a non-shared > context. [1] > > I have found that the culprit object is one of those changed in the step (c), > and I have found that touching the shared EO in the SEC before the fetch > helps: the shared EO gets re-loaded, and the fetch works as presumed > (returning the shared EO in the SEC). Now, I do this: > > - whenever the SharedEditingContextInitializedObjectsNotification comes, I > record the SEC; > - after the shared EOs are changed (in an EC with null SEC) and saved, I go > through all the SECs recorded; for each of them I get all its > registeredObjects, and for each of them call eo.storedValueForKey(anyKey). If > the object has been changed, this re-loads it in SEC, and subsequent fetching > works properly. > > This seems to me extremely weird. Can you understand what the heck happens > there and why? > > Thanks and all the best, > OC > > [1] it looks like this: with fetch code like > > println "FETCH $ec SEC:$ec.sharedEditingContext > RELS:${EOModelGroup.defaultGroup.entityNamed(fs.entityName).relationships}" > found=ec.objectsWithFetchSpecification(fs) > println "FETCH $ec SEC:$ec.sharedEditingContext got $found" > > it quite consistently crashes like this: > > FETCH er.extensions.eof.ERXEC@11a11fbb > SEC:com.webobjects.eocontrol.EOSharedEditingContext@79c3f01f RELS:[] > 9301 [WorkerThread5] INFO er.transaction.adaptor.Exceptions - Database > Exception occured ... > ... ... > Caused by: java.lang.IllegalArgumentException: EOEditingContext: > initializeObject: attempt to initialize object with global ID > _EOIntegralKeyGlobalID[DBDFList (java.lang.Integer)100] that exists in a > shared context via a non-shared context. The object model may have a > relationship from a shared entity to a non-shared entity. Disable or remove > the relationship from the model. > at > com.webobjects.eocontrol.EOEditingContext.initializeObject(EOEditingContext.java:3760) > at er.extensions.eof.ERXEC.initializeObject(ERXEC.java:1237) > at > com.webobjects.eoaccess.EODatabaseChannel$_EODatabaseChannelFetchResult.initializeObjects(EODatabaseChannel.java:496) > at > com.webobjects.eoaccess.EODatabaseContext._objectsWithFetchSpecificationEditingContext(EODatabaseContext.java:3090) > at > com.webobjects.eoaccess.EODatabaseContext.objectsWithFetchSpecification(EODatabaseContext.java:3195) > 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:1307) > at > com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4444) > at > com.webobjects.eocontrol.EOEditingContext$objectsWithFetchSpecification$0.call(Unknown > Source) > > if, though, I programmatically find the object which is to be fetched in the > SEC and touch it like this: > > println "FETCH $ec SEC:$ec.sharedEditingContext > RELS:${EOModelGroup.defaultGroup.entityNamed(fs.entityName).relationships}" > ec.sharedEditingContext.registeredObjects.findAll { > it.entityName==fs.entityName && fs.qualifier.evaluateWithObject(it) }.each { > it.storedValueForKey('title') // sufficient to touch the thing to reload it > in SEC; without it is never reloaded and causes the crash > } > found=ec.objectsWithFetchSpecification(fs) > > it never crashes; and, as soon as storedValueForKey is called, the object is > re-loaded in the SEC. It is sufficient to out-comment the storedValueForKey > to get the attempt to initialize object ... that exists in a shared context > crash back. Far as the storedValueForKey is there, it does not crash. > > > On 26. 9. 2018, at 7:12 PM, Chuck Hill <ch...@gevityinc.com > <mailto:ch...@gevityinc.com>> wrote: > > Hi OC, > > No, no magic like that. At least not that I know of. Subclassing > EOEditingContext, EOSharedEditingContext, maybe EODatabaseContext is probably > your best bet to pursue this. > > Chuck > > From: "ocs@ocs" <o...@ocs.cz <mailto:o...@ocs.cz>> > Date: Wednesday, September 26, 2018 at 8:40 AM > To: Chuck Hill <ch...@gevityinc.com <mailto:ch...@gevityinc.com>> > Cc: WebObjects-Dev Mailing List <webobjects-dev@lists.apple.com > <mailto:webobjects-dev@lists.apple.com>> > Subject: Re: Flattened one-side M:N fails wildly with SharedEC > > Chuck, > > > > On 19 Sep 2018, at 9:57 PM, Chuck Hill <ch...@gevityinc.com > <mailto:ch...@gevityinc.com>> wrote: > Uh oh, the dreaded Schrödinger EOF behaviour! Have you figured anything out? > > Alas, nope. The darned “The shared context recently initialized the object > ...” thing occurs intermittently, and whenever I add extra logs to find the > culprit, it disappears. To occur again the next day or the next week. > > Is there some trick to set up something somewhere so that > > (a) until the SEC tries to load a non-shared object, all runs normally, there > are no extra logs nor big performance delays, > (b) but, as soon as that happens, I get a very detailed log which would not > only say which object is the culprit, but also the reason why has it been > loaded into SEC, through which relationship, etc.? > > Thanks and all the best, > OC > > > > > From: "ocs@ocs" <o...@ocs.cz <mailto:o...@ocs.cz>> > Date: Wednesday, August 29, 2018 at 12:38 PM > To: Chuck Hill <ch...@gevityinc.com <mailto:ch...@gevityinc.com>> > Cc: WebObjects-Dev Mailing List <webobjects-dev@lists.apple.com > <mailto:webobjects-dev@lists.apple.com>> > Subject: Re: Flattened one-side M:N fails wildly with SharedEC > > Darn... > > > > > might have been caused by something else, which is just loosely related to > the change — a log in the code for all I know; the Schrödinger EOF behaviour > did bit me once or twice already > > ... I should have not written this part! > > I have seen the blasted “The shared context recently initialized the object > ...” thing again. > > Added log to pursue it. It did not happen. > > Removed the log. It still did not happen. > > Curiouser and curiouser... > > Thanks and all the best, > OC > > > > > On 29 Aug 2018, at 7:49 PM, ocs@ocs <o...@ocs.cz <mailto:o...@ocs.cz>> wrote: > > Chuck, > > > > > On 29 Aug 2018, at 7:14 PM, Chuck Hill <ch...@gevityinc.com > <mailto:ch...@gevityinc.com>> wrote: > I am not sure that I am following this correctly. The rule is that no Shared > EO should have a relationship to anything that is not also a Shared EO. > > The opposite direction (from normal EC to SEC) should be all right though, > should it not? > > > > > That includes the tables not materialized into an EO. > > I do not follow here. > > My shared entity S had no relationship to non-shared ones at all. Not even an > empty one; none altogether. > > My non-shared entity A has a to-many relationship “aaa” to a non-shared B; B > has a to-one relationship “bbb” to shared S (no inverse here). B is the M:N > table, i.e., it contains just the A's and S's PKs. > > When non-shared A contained a flattened relationship “ddd” defined as > “aaa.bbb”, EOF kept trying to load A into SEC (which naturally failed). > > I've removed the flattened “ddd” from the model (no other change there), and > implemented its behaviour manually (in A just getting “aaa” programmatically, > and then for all its objects collecting their “bbb”'s), and the problem > disappeared; A has been no more loaded to SEC. > > Of course, it might have been caused by something else, which is just loosely > related to the change — a log in the code for all I know; the Schrödinger EOF > behaviour did bit me once or twice already :) it does seem very weird to me > that the flattened thing should be the culprit; that's why I am asking > whether such kind of behaviour is to be expected, or whether I should try to > hunt for the culprit elsewhere. > > Thanks and all the best, > OC > > > > > > From: Webobjects-dev > <webobjects-dev-bounces+chill=gevityinc....@lists.apple.com > <mailto:webobjects-dev-bounces+chill=gevityinc....@lists.apple.com>> on > behalf of "ocs@ocs" <o...@ocs.cz <mailto:o...@ocs.cz>> > Date: Wednesday, August 29, 2018 at 8:28 AM > To: WebObjects-Dev Mailing List <webobjects-dev@lists.apple.com > <mailto:webobjects-dev@lists.apple.com>> > Subject: Flattened one-side M:N fails wildly with SharedEC > > Hi there, > > just have bumped into another weird (at least to me) behaviour. > > In my model, there used to be a very standard M:N relationship, which > exploits an “invisible” intermediate table, flattened “direct” relationships > ad both sides. > > One of the sides lately went to the sharedEC; thus I made sure to delete this > side's flattened relationship. The other side and the intermediate table both > stay outside of the sharedEC, so I thought that is all right. > > It failed miserably with “The shared context recently initialized the object > <non-shared-one> which is already registered in this context yadda yadda”, > i.e., EOF for some godforsaken reason kept loading the non-shared object (the > one whose relationship remained intanct) into SEC along with the shared one > (whose relationship were removed all right, no traces remained; I have > checked about zillion times). > > Out of desperation, I have just tried to remov the flattened relationship > from the non-shared side, exposing instead the intermediate table, and > replacing the flattened relationship by something like > > === > List availablePrototypes { // this is how the original flattened rel has > been named > def mn=this.db_Prototype_DataBlock // 1:N relationship to the > intermediate table, exposed > mn.collect { > it.valueForKey('prototype') // N:1 relationship from the inmdt > table to the shared object > } > } > === > > and it seems to work all right :-O So, it looks like the culprit was the > existence of the flattened rel with definiton > “db_Prototype_DataBlock.prototype” at the non-shared side. > > Is that the intended behaviour? Seems pretty weird to me, but as always, I > might be overlooking something of importance. Or should that work even with > the flattened relationship, and the problems mean I must have done something > wrong elsewhere? > > Thanks and all the best, > OC > > _______________________________________________ > Do not post admin requests to the list. They will be ignored. > Webobjects-dev mailing list (Webobjects-dev@lists.apple.com > <mailto:Webobjects-dev@lists.apple.com>) > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz > <https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz> > > This email sent to o...@ocs.cz <mailto:o...@ocs.cz>
_______________________________________________ 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