Ran into this and thought I should share :)

If you have a table that relates to itself, prefetching across that 
relationship can wreck your object graph. As an example, let’s say you have an 
Employee entity. Employee has a relationship to Employee named manager, the 
reverse of which is subordinates. Further assume manager is top level so a 
manager’s manager is himself. If you are given a single Employee, and want to 
know something about all subordinates, you may do something like

EOQualifier q = Employee.SALARY.greaterThan(5000);
EOFetchSpec fs = …
fs.setPrefetchingKeyPaths(“manager.subordinates.restOfPath”);

The problem is in how EOF handles prefetches, it builds qualifier’s backwards 
for the original fetch. So first it fetches Employee with salary > 5000. Next 
it fetches managers, which are also employees, so the qualifier on that 
prefetch is subordinates.salary > 5000, then on the next step, rather than 
producing manager.subordinates.salary, it notices the relationship is circular 
and just lops off subordinates leaving salary.

In my case, this left me with a qualifier that only matched the manager for the 
prefetch. What’s worse, the subordinates relationship was then only populated 
with the manager by EOF. So in a case where manager.subordinates().count() 
should equal 5, it was only 1.

This appears to be happening in EOKeyValueQualifier’s sql generation support 
class. It looks like it might be something that could be patched in 
ERXExtensions as there is already some patching in there for stuff like the ERX 
regex qualifiers and such.

ERXBatchFetchingUtils works properly in this case, but that is significantly 
slower than prefetching due to the sql generated.

My workaround for this problem seems to work. I created a second copy of the 
relationship. So in the above example, I have manager, boss, subordinates, and 
underlings. boss == manager, and underlings == subordinate. I make these 
duplicate relationships non-class properties. Then with a ERXKey that I place 
in Employee, I can make my prefetch path look like 
“boss.subordinates.restOfPath”. Both ends of the relationship must exist or EOF 
finds the subordinates relationship anyway and the bug still happens. I also 
had to implement handleUnbound for the Employee on the boss relationship path. 
Since these are basically read-only relationships for my case, it works. It may 
not work as smoothly in others.
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to