Discussion:
Flattened one-side M:N fails wildly with SharedEC
ocs@ocs
2018-08-29 15:28:26 UTC
Permalink
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
Chuck Hill
2018-08-29 17:14:53 UTC
Permalink
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. That includes the tables not materialized into an EO.

Chuck


From: Webobjects-dev <webobjects-dev-bounces+chill=***@lists.apple.com> on behalf of "***@ocs" <***@ocs.cz>
Date: Wednesday, August 29, 2018 at 8:28 AM
To: WebObjects-Dev Mailing List <webobjects-***@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
ocs@ocs
2018-08-29 17:49:28 UTC
Permalink
Chuck,
Post by Chuck Hill
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?
Post by Chuck Hill
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
Post by Chuck Hill
Date: Wednesday, August 29, 2018 at 8:28 AM
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
ocs@ocs
2018-08-29 19:38:18 UTC
Permalink
Darn...
Post by ***@ocs
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
Post by ***@ocs
Chuck,
Post by Chuck Hill
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?
Post by Chuck Hill
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
Post by Chuck Hill
Date: Wednesday, August 29, 2018 at 8:28 AM
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.
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz
Chuck Hill
2018-09-19 19:57:24 UTC
Permalink
Uh oh, the dreaded Schrödinger EOF behaviour! Have you figured anything out?

Chuck

From: "***@ocs" <***@ocs.cz>
Date: Wednesday, August 29, 2018 at 12:38 PM
To: Chuck Hill <***@gevityinc.com>
Cc: WebObjects-Dev Mailing List <webobjects-***@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.cz<mailto:***@ocs.cz>> wrote:

Chuck,


On 29 Aug 2018, at 7:14 PM, Chuck Hill <***@gevityinc.com<mailto:***@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=***@lists.apple.com<mailto:webobjects-dev-bounces+chill=***@lists.apple.com>> on behalf of "***@ocs" <***@ocs.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 8:28 AM
To: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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-***@lists.apple.com<mailto:Webobjects-***@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz

This email sent to ***@ocs.cz
ocs@ocs
2018-09-26 15:40:29 UTC
Permalink
Chuck,
Post by Chuck Hill
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
Post by Chuck Hill
Date: Wednesday, August 29, 2018 at 12:38 PM
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
Chuck,
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
Date: Wednesday, August 29, 2018 at 8:28 AM
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.
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz <https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz>
Chuck Hill
2018-09-26 17:12:17 UTC
Permalink
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.cz>
Date: Wednesday, September 26, 2018 at 8:40 AM
To: Chuck Hill <***@gevityinc.com>
Cc: WebObjects-Dev Mailing List <webobjects-***@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 <***@gevityinc.com<mailto:***@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.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 12:38 PM
To: Chuck Hill <***@gevityinc.com<mailto:***@gevityinc.com>>
Cc: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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.cz<mailto:***@ocs.cz>> wrote:

Chuck,



On 29 Aug 2018, at 7:14 PM, Chuck Hill <***@gevityinc.com<mailto:***@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=***@lists.apple.com<mailto:webobjects-dev-bounces+chill=***@lists.apple.com>> on behalf of "***@ocs" <***@ocs.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 8:28 AM
To: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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-***@lists.apple.com<mailto:Webobjects-***@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz

This email sent to ***@ocs.cz<mailto:***@ocs.cz>
o***@ocs.cz
2018-09-29 01:56:25 UTC
Permalink
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 ***@11a11fbb SEC:***@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.
Post by Chuck Hill
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
Date: Wednesday, September 26, 2018 at 8:40 AM
Subject: Re: Flattened one-side M:N fails wildly with SharedEC
Chuck,
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
Date: Wednesday, August 29, 2018 at 12:38 PM
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
Chuck,
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
Date: Wednesday, August 29, 2018 at 8:28 AM
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.
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz <https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz>
Chuck Hill
2018-10-02 06:10:48 UTC
Permalink
Hi OC!

I am using Microsoft Outlook which does not believe that in-line quoting is useful. So email salad:

Your second problem seems mostly like what I would expect.

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.

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.

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. 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.


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?

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.

Chuck



From: "***@ocs.cz" <***@ocs.cz>
Date: Friday, September 28, 2018 at 6:56 PM
To: Chuck Hill <***@gevityinc.com>
Cc: WebObjects-Dev Mailing List <webobjects-***@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 ***@11a11fbb SEC:***@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 <***@gevityinc.com<mailto:***@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.cz<mailto:***@ocs.cz>>
Date: Wednesday, September 26, 2018 at 8:40 AM
To: Chuck Hill <***@gevityinc.com<mailto:***@gevityinc.com>>
Cc: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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 <***@gevityinc.com<mailto:***@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.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 12:38 PM
To: Chuck Hill <***@gevityinc.com<mailto:***@gevityinc.com>>
Cc: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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.cz<mailto:***@ocs.cz>> wrote:

Chuck,




On 29 Aug 2018, at 7:14 PM, Chuck Hill <***@gevityinc.com<mailto:***@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=***@lists.apple.com<mailto:webobjects-dev-bounces+chill=***@lists.apple.com>> on behalf of "***@ocs" <***@ocs.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 8:28 AM
To: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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-***@lists.apple.com<mailto:Webobjects-***@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz

This email sent to ***@ocs.cz<mailto:***@ocs.cz>
ocs@ocs
2018-10-02 10:51:17 UTC
Permalink
Chuck,
Post by o***@ocs.cz
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 :(
Post by o***@ocs.cz
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.
Post by o***@ocs.cz
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 :)
Post by o***@ocs.cz
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 :/
Post by o***@ocs.cz
(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?
Post by o***@ocs.cz
- 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
Post by o***@ocs.cz
Date: Friday, September 28, 2018 at 6:56 PM
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).
(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]
- 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"
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)
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.
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
Date: Wednesday, September 26, 2018 at 8:40 AM
Subject: Re: Flattened one-side M:N fails wildly with SharedEC
Chuck,
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
Date: Wednesday, August 29, 2018 at 12:38 PM
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
Chuck,
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
Date: Wednesday, August 29, 2018 at 8:28 AM
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.
https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz <https://lists.apple.com/mailman/options/webobjects-dev/ocs%40ocs.cz>
Chuck Hill
2018-09-19 19:56:18 UTC
Permalink
Hi OC,

Sorry, this got lost (scrolled off the screen) in my in-box.

I am not sure why this is happening, but what you are describing is a bug. Somewhere
 Those relationships and the flattened relationship should work as you expect.


Chuck



From: "***@ocs" <***@ocs.cz>
Date: Wednesday, August 29, 2018 at 10:49 AM
To: Chuck Hill <***@gevityinc.com>
Cc: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com>
Subject: Re: Flattened one-side M:N fails wildly with SharedEC

Chuck,


On 29 Aug 2018, at 7:14 PM, Chuck Hill <***@gevityinc.com<mailto:***@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=***@lists.apple.com<mailto:webobjects-dev-bounces+chill=***@lists.apple.com>> on behalf of "***@ocs" <***@ocs.cz<mailto:***@ocs.cz>>
Date: Wednesday, August 29, 2018 at 8:28 AM
To: WebObjects-Dev Mailing List <webobjects-***@lists.apple.com<mailto:webobjects-***@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
Loading...