Conversation
Signed-off-by: ruthes00 <ruthes00@gmail.com>
…P 405 Fixes spring-projectsGH-1810 When a JPA entity exposes a bidirectional association via Spring Data REST, the inverse (non-owning) side is annotated with mappedBy on @onetomany, @manytomany, or @OnetoOne. JPA only persists association changes from the owning side; writes on the inverse side are silently ignored by the JPA provider even though the entity is saved. This caused SDR to return HTTP 204 (No Content) implying success while making no actual database changes. This commit introduces InverseSideAssociationDetector, which uses reflection to inspect JPA annotations on a PersistentProperty and detect a non-empty mappedBy attribute. The detection is performed via ClassUtils.forName so that the class degrades gracefully when jakarta.persistence is absent from the classpath (it is an optional dependency of the webmvc module). RepositoryPropertyReferenceController.doWithReferencedProperty now calls this detector before executing any write operation (PUT, POST, PATCH, DELETE). If the property is the inverse side of a JPA association, the request is rejected with HTTP 405 Method Not Allowed and an Allow: GET header, along with a descriptive message directing the caller to update the owning side instead. GET requests on inverse-side associations are unaffected and continue to work normally. Tests added: - InverseSideAssociationDetectorUnitTests: 6 unit tests covering all three annotation types (@onetomany, @manytomany, @OnetoOne) with and without mappedBy, plus @manytoone (always owning side). - RepositoryPropertyReferenceControllerIntegrationTests: 4 new JPA integration tests verifying that PUT/POST on the inverse side throw HttpRequestMethodNotSupportedException, GET on the inverse side returns HTTP 200, and PUT on the owning side continues to work normally. Signed-off-by: ruthes00 <ruthes00@gmail.com>
ruthst00
force-pushed
the
issue/1810
branch
from
September 13, 2026 19:07
d7ffd2c to
d8ce7cc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1810
The issue GH-1810 still existed in SDR 5.0.7 (and the current
5.2.0-1810-SNAPSHOTbranch). The bug: when a client sends a PUT/POST/PATCH/DELETE to the inverse (mappedBy) side of a JPA bidirectional association (e.g.PUT /authors/{id}/bookswhereAuthor.bookshas@ManyToMany(mappedBy="authors")), SDR would return HTTP 204 implying success — but JPA silently ignores writes on the non-owning side, so no database changes were made.The fix (commit
d7ffd2ce) adds two new files and modifies two existing ones:InverseSideAssociationDetector(new) — usesClassUtils.forName+ reflection to detect a non-emptymappedByattribute on@OneToMany,@ManyToMany, or@OneToOneannotations. Gracefully returnsfalsewhenjakarta.persistenceis absent from the classpath.RepositoryPropertyReferenceController—doWithReferencedPropertynow callsInverseSideAssociationDetector.isInverseSide()before any write operation. If the property is the inverse side, it throwsHttpRequestMethodNotSupportedExceptionwhich the existing@ExceptionHandlerconverts to HTTP 405 Method Not Allowed withAllow: GETand a descriptive message directing the caller to update the owning side instead. GET requests are unaffected.InverseSideAssociationDetectorUnitTests(new) — 6 unit tests covering all three annotation types with/withoutmappedBy.RepositoryPropertyReferenceControllerIntegrationTests— 4 new JPA integration tests verifying PUT/POST on the inverse side throw the exception, GET still works, and PUT on the owning side continues to work normally. All 15 tests (9 unit + 6 integration) pass.