Skip to content

Fix issue where links to subclasses of abstract class (aggregate root) are not rendered correctly - #2609

Open
ruthst00 wants to merge 2 commits into
spring-projects:mainfrom
ruthst00:issue/1445
Open

ruthst00 wants to merge 2 commits into
spring-projects:mainfrom
ruthst00:issue/1445

Conversation

@ruthst00

Copy link
Copy Markdown

Fixes #1445

The Bug: When a Spring Data REST repository is typed to an abstract JPA entity (e.g. MealRepository extends JpaRepository<Meal, Long>) and the actual instances returned at runtime are concrete subclasses (e.g. Dinner extends Meal), DefaultSelfLinkProvider was generating incorrect self-links pointing to a non-existent subclass resource path (e.g. /dinner/1) instead of the correct base-class resource path (e.g. /meals/1). This made the self-links unresolvable (404).

Root Cause: DefaultSelfLinkProvider.createSelfLinkFor() called entityLinks.linkToItemResource(instance.getClass(), id) using the concrete runtime type (Dinner) directly. Since no repository is registered for Dinner, EntityLinks fell back to generating a path from the class name.

The Fix (commit e4d82d24):

  1. DefaultSelfLinkProvider — Added a resolveRepositoryType() method that walks up the superclass hierarchy from the concrete type to find the nearest ancestor that is the exact domain type of a registered repository. The check uses Repositories.getRepositoryInformationFor(type) and verifies the declared domain type matches exactly (distinguishing Meal from Dinner, since Repositories.hasRepositoryFor() returns true for both via hierarchy lookup). Added an optional Repositories constructor parameter.
  2. RepositoryRestMvcConfiguration — Updated selfLinkProvider() bean method to inject the Repositories bean.
  3. Test infrastructure — Added MealRepository and DataRest1080Tests with 4 integration tests covering: correct self-link path, resolvable self-link, subclass field serialization, and collection resource self-links.

All 4 new tests pass; the 2 pre-existing test failures (RepositoryControllerIntegrationTests, PersistentEntitySerializationTests) were confirmed to exist before this fix and are unrelated.

  • You have read the Spring Data contribution guidelines.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

Signed-off-by: ruthes00 <ruthes00@gmail.com>
…e repositories

When a Spring Data REST repository is typed to an abstract JPA entity
(e.g. MealRepository extends JpaRepository<Meal, Long>) and the actual
instances returned at runtime are concrete subclasses (e.g. Dinner extends
Meal), DefaultSelfLinkProvider was generating incorrect self-links pointing
to a non-existent subclass resource path (e.g. /dinner/1) instead of the
correct base-class resource path (e.g. /meals/1).

Root cause: DefaultSelfLinkProvider.createSelfLinkFor() called
entityLinks.linkToItemResource(instance.getClass(), id) using the concrete
runtime type (Dinner) directly. Since no repository is registered for
Dinner, EntityLinks fell back to generating a path from the class name,
producing /dinner/1.

Fix: Introduce a resolveRepositoryType() method in DefaultSelfLinkProvider
that walks up the superclass hierarchy from the concrete type to find the
nearest ancestor that is the exact domain type of a registered repository.
The check uses Repositories.getRepositoryInformationFor(type) and verifies
that the declared domain type matches exactly, distinguishing Meal (the
repository domain type) from Dinner (a subclass that
Repositories.hasRepositoryFor() also returns true for via hierarchy lookup).

To support this, DefaultSelfLinkProvider gains an optional Repositories
constructor parameter, and RepositoryRestMvcConfiguration.selfLinkProvider()
is updated to inject the Repositories bean.

Resolves: spring-projectsGH-1445

Signed-off-by: Steve Rutherford <ruthes00@example.com>
Signed-off-by: ruthes00 <ruthes00@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Links to subclasses of abstract class (aggregate root) are not rendered correctly [DATAREST-1080]

2 participants