Skip to content

fix(doctrine): guard unmapped relation links in ORM handleLinks#8293

Open
soyuka wants to merge 2 commits into
api-platform:4.3from
soyuka:fix/graphql-transient-self-reference-link
Open

fix(doctrine): guard unmapped relation links in ORM handleLinks#8293
soyuka wants to merge 2 commits into
api-platform:4.3from
soyuka:fix/graphql-transient-self-reference-link

Conversation

@soyuka

@soyuka soyuka commented Jun 12, 2026

Copy link
Copy Markdown
Member
Q A
Branch? 4.3
Bug fix? yes
New feature? no
Deprecations? no
Issues Fixes #8292
License MIT

A GraphQL item query crashed with a Doctrine MappingException when the queried resource had a public property typed as the resource class but not mapped as a Doctrine association (e.g. a transient/runtime-only self reference).

LinkFactory::createLinksFromRelations() builds a relation Link for any property whose native type resolves to a resource class — without checking it is an actual association. The GraphQL root-item link filter in Doctrine\Common\State\LinksHandlerTrait::getLinks() keeps self references (toClass === resourceClass). Doctrine\Orm\State\LinksHandlerTrait::handleLinks() then called getAssociationMapping() unguarded and threw:

No mapping found for field 'relatedButNotMapped' on class 'App\Entity\Foo'.

Regression introduced in #8237 (GraphQL item query dispatched through its own provider, 4.3).

This guards the association lookup with hasAssociation() — matching the guard already present in the ODM LinksHandlerTrait. When the property is not a mapped association the link is skipped; the identifier-self link still applies WHERE id = X.

Added a functional GraphQL test (ORM): two persisted items, queries the second, asserts no errors and the correct item is returned (proving the identifier filter still applies after the unmapped link is skipped).

soyuka added 2 commits June 12, 2026 12:44
A GraphQL item query crashed with a Doctrine MappingException when the
resource had a public property typed as the resource class but not mapped
as a Doctrine association (e.g. a transient self reference).

LinkFactory builds a relation Link from the property's native type, and
the GraphQL root-item link filter keeps self references (toClass ===
resourceClass). The ORM LinksHandlerTrait then called getAssociationMapping()
unguarded, throwing "No mapping found for field ... on class ...".

Skip the link when the property is not an actual association, matching the
existing hasAssociation() guard in the ODM trait. The identifier-self link
still applies WHERE id=X.

Closes api-platform#8292
The new hasAssociation() guard in handleLinks queries the mocked
ClassMetadata, which returned false by default and skipped the join the
test expected. Stub it to true for the mapped 'company' association.
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