Problems with extra N+1 requests - likely due to poor mapping defns, but not sure how to rectify
ebenzacar@...
I'm having some strange RDBMS N+1 calls most likely due to my mappings, but am not sure if this is a DN Persistence configuration issue or a mapping issue. I'm using MSSQL.
My problem is that I have an Object "Person" which has some audit fields "addPerson" and "modPerson". Both "addPerson" and "modPerson" are simple N-1 relations. Conceptually like the following: // InheritanceStrategy=New-table Class Person extends Audit{
String name;
int age; }
// InheritanceStrategy=subclass-table Class Audit{ AuditPerson addPerson;
AuditPerson modPerson;
}
Class AuditPerson{ String username; } When I retrieve the Person (using a datastore identity), I see an SQL Query which selects the primitive fields but not the embedded Objects. Something like: "Select name, age FROM Person where ID = 123". When I try to convert to a DTO and read the `addPerson`, and `modPerson` fields, DN then launches the next queries:
|
|
Audit fields "addPerson" and "modPerson" aren't embedded (exist in the same table), they are related (have their own table), using JDO terminology ... or at least without seeing your mapping (XML/annotations) that's what it looks like.
Your mapping definition controls where things are stored, and what is in the default fetch group. Your runtime API usage defines what is in the active fetch group. What is in the fetch group defines what is fetched ... clue in the name. Kodo maybe didn't have JDO (2) fetch groups. You rectify it by specifying the appropriate fetching (group) for the appropriate moment in the API usage.
|
|
ebenzacar@...
Thanks Andy. Fair enough (embedded vs related).
Eric Eric
|
|
With a single object relation with the FK at the selected object side there are only 3 things that would be feasible.
If you always want to load the related object with just the PK field(s) then you can always mark it as "fetch-fk-only" on that field, in the metadata. If you only sometimes want to load the related object with just the PK fields, then put the field in the fetch plan for the SELECT, but also remove all other fields of the related object from the fetch plan (so it doesn't add a join to the related object).
|
|
ebenzacar@...
I've tried to add the extension definition to my package jdo file but either it isn't working as I expect, or I've defined it incorrectly. This is what I added:
<field name="addPerson" column="ADDPERSON" default-fetch-group="true"> With this definition, I was expecting that the object retrieval would basically retrieve the FK value for addPerson from my Manufacturer object. However, it seems to be trying to retrieve the full object, and puts itself in an endless loop for some reason, causing a StackOverflow. The datamodel isn't exactly what I listed above, but rather has a bit of a circular design (ie: the AuditPerson actually contains an instance of Audit). When trying to debug the issue further, I see that DN is calling `dnReplaceFields()` method on my Manufacturer object, but it is difficult to identify which field it is. I can see the field index value which is causing the endless loop, but can't determine which fieldname the index maps to. I cannot find the metadata/mapping information where the fieldname is mapped to the field number. In my case, when I put the debugger on the dnReplaceField in the call stack, I see that it is trying to load field 56, and that this field is causing the infinite loop. How/where can I identify which fieldname field 56 is mapped to? Similarly, the DN logs show me what I think is a list of fields that are loaded/not loaded when the object is retreived from cache (loadedFlags) (ex: (id="zzzz" taken from Level 1 cache (loadedFlags="[YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYNNNNNNNNNNN]"). But how do I identify which index is which field? I would have expected that setting datanucleus.maxFetchDepth=1 would prevent any recursion from happening, but it is still endlessly trying to reload that same field #56. Removing the `addPerson/modPerson` from the default-fetch-group stops the infinite loop. Any suggestions what/how to investigate next would be appreciated.
Thanks, Eric
|
|
That metadata extension works for me in this sample. How you apply it is up to you
|
|
Thanks; will look into that more closely. Thanks, Eric
|
|
|
|
On Fri, Apr 30, 2021 at 05:03 AM, Andy wrote:
Strange; that doesn't seem to align with my "stuck" index. I tried taking the field list and sorting them alphabetically, but the ~56th alphabetical fieldname doesn't align at with the problematic field.
|
|
Hi @Andy, Eric
|
|