Skip to content

Port /data/query/enhanced/v2/{id} to node, SummaryEntity included - #476

Merged
adamjohnwright merged 2 commits into
mainfrom
port/enhanced-v2
Oct 15, 2026
Merged

adamjohnwright merged 2 commits into
mainfrom
port/enhanced-v2

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

The site's busiest content call: the Pathway Browser's details panel and
the website's detail pages fetch every object they show through it
(fetchIncomingRelationships, summariseReferenceEntity and includeDisease
all true, JSOG, nested-aggregated).

  • The query is graph-core's findEnhancedObjectById, as written in
    AdvancedDatabaseObjectRepository. When summarising a reference entity,
    it covers the object and every physical entity referring to it, with
    their neighbours (both ways unless needsIncoming says not) and the
    repository's second-step expansions. UpdateTrackers are excluded, and
    so is disease data unless includeDisease.
  • A reference entity, asked to summarise, is written as content-service's
    SummaryEntity, rebuilt in node (summaryEntity). The constructor's
    copies by reference type. The physical entities are sorted by modified
    residues then dbId, in the reference entity's own list too, as Java
    sorts in place. Each accessor merges through SummaryEntity's getter and
    PhysicalEntity's setter: a list unioned once per element, the
    stoichiometric ones expanded and re-aggregated, the species and
    reference type of the last entity that has one.
  • SummaryEntity's Jackson layout comes from the deployed classes like
    everything else. snapshot-domain reads it serialise-only, keeping it
    out of SDN's mapping context. Its two computed getters are implemented,
    and the generator refuses to run until they are.
  • Three primitive booleans with defaults are parsed as Spring parses them
    (blank is a 400 naming boolean). An object found only with disease
    data, asked for without, is looked up again with it, as in Java.

Against Java, 270 objects (reactions, pathways, complexes, EWASs, sets,
chemicals, gene products, molecules), spaced out per the load rules:

  • default view: 270 of 270 byte-identical;
  • the site's nested JSOG view: 270 of 270 identical as object graphs.
    The nested view's getter-only key order is the JVM's of the day (see
    writeDomain). That moves where an object is written in full and so its
    JSOG number, and those views are compared that way. Node took 5.0s in
    all, Java 13.1s.

Tests failed before the change. Reverting the residue sort, the
de-duplication or the species merge each fails one. nginx -t passes.

🤖 Generated with Claude Code

adamjohnwright and others added 2 commits October 15, 2026 15:11
The site's busiest content call: the Pathway Browser's details panel and
the website's detail pages fetch every object they show through it
(fetchIncomingRelationships, summariseReferenceEntity and includeDisease
all true, JSOG, nested-aggregated).

- The query is graph-core's findEnhancedObjectById, as written in
  AdvancedDatabaseObjectRepository. When summarising a reference entity,
  it covers the object and every physical entity referring to it, with
  their neighbours (both ways unless needsIncoming says not) and the
  repository's second-step expansions. UpdateTrackers are excluded, and
  so is disease data unless includeDisease.
- A reference entity, asked to summarise, is written as content-service's
  SummaryEntity, rebuilt in node (summaryEntity). The constructor's
  copies by reference type. The physical entities are sorted by modified
  residues then dbId, in the reference entity's own list too, as Java
  sorts in place. Each accessor merges through SummaryEntity's getter and
  PhysicalEntity's setter: a list unioned once per element, the
  stoichiometric ones expanded and re-aggregated, the species and
  reference type of the last entity that has one.
- SummaryEntity's Jackson layout comes from the deployed classes like
  everything else. snapshot-domain reads it serialise-only, keeping it
  out of SDN's mapping context. Its two computed getters are implemented,
  and the generator refuses to run until they are.
- Three primitive booleans with defaults are parsed as Spring parses them
  (blank is a 400 naming `boolean`). An object found only with disease
  data, asked for without, is looked up again with it, as in Java.

Against Java, 270 objects (reactions, pathways, complexes, EWASs, sets,
chemicals, gene products, molecules), spaced out per the load rules:
- default view: 270 of 270 byte-identical;
- the site's nested JSOG view: 270 of 270 identical as object graphs.
The nested view's getter-only key order is the JVM's of the day (see
writeDomain). That moves where an object is written in full and so its
JSOG number, and those views are compared that way. Node took 5.0s in
all, Java 13.1s.

Tests failed before the change. Reverting the residue sort, the
de-duplication or the species merge each fails one. nginx -t passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #476. Spring uses a parameter's defaultValue only when the
argument is exactly "". A repeated parameter arrives as a String[]: an
empty first element cannot become a primitive, so Spring converts the
joined values and fails. Java answers ?includeDisease=&includeDisease=true
with a 400 "Invalid boolean value [,true]", and ?maxDepth=&maxDepth=2
(in-depth) with a 400 "For input string: ",2"". Node took the defaults.
springPrimitiveBoolean and springIntWithDefault now default only for no
value or a single empty one. 4 of 4 cases match Java. Tests failed before
the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit 0f557f0 into main Oct 15, 2026
6 checks passed
@adamjohnwright
adamjohnwright deleted the port/enhanced-v2 branch October 15, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant