-
Notifications
You must be signed in to change notification settings - Fork 565
POST/PUT to entity with @JsonProperty annotated relation does not work #2165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Normally, when creating and updating (POST/PUT) an entity via the REST endpoints, you can use the URL of the relation target. (e.g.: send `{"package": "/packages/1"}` when `package` is a JPA `@OneToOne` relation) Now this also takes into account when the JPA relation is annotated with `@JsonProperty()` to change the serialized name. Fixes spring-projects#2165
Normally, when creating and updating (POST/PUT) an entity via the REST endpoints, you can use the URL of the relation target. (e.g.: send `{"package": "/packages/1"}` when `package` is a JPA `@OneToOne` relation) Now this also takes into account when the JPA relation is annotated with `@JsonProperty()` to change the serialized name. Fixes spring-projects#2165
Normally, when creating and updating (POST/PUT) an entity via the REST endpoints, you can use the URL of the relation target. (e.g.: send `{"package": "/packages/1"}` when `package` is a JPA `@OneToOne` relation) Now this also takes into account when the JPA relation is annotated with `@JsonProperty()` to change the serialized name. Closes spring-projects#2165
Thanks for the detailed write up. I took a look at this and I think we have to clarify a few things before moving on. I think the property model that both Jackson and Spring Data build for the arrangement you present is not working the way you assume it to work. The internal name not being reported properly seems to be cause by Jackson invalidly connecting the To cite your test case: class PetOwner {
@Getter(value = AccessLevel.NONE)
@JsonProperty("package")
Package _package;
public Package getPackage() {
return _package;
}
} Spring Data defaults to field access and thus the only property found is named I'll push a fix that will use our |
…deserialization. Revert the changes that employed manual annotation lookup as that would cause invalid associations of fields and accessor methods for properties shadow renamed. Instead, we now use MappedProperties that already contains a mapping between the Jackson field names and Spring Data property names. Fixes: #2165 $ Conflicts: $ spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java $ spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java
Normally, when creating and updating (POST/PUT) an entity via the REST endpoints, you can use the URL of the relation target. (e.g.: send `{"package": "/packages/1"}` when `package` is a JPA `@OneToOne` relation). Now this also takes into account when the JPA relation is annotated with `@JsonProperty` to change the serialized name. Add unit tests for linkable associations. Issue: #2165
…deserialization. Revert the changes that employed manual annotation lookup as that would cause invalid associations of fields and accessor methods for properties shadow renamed. Instead, we now use MappedProperties that already contains a mapping between the Jackson field names and Spring Data property names. Fixes: #2165 $ Conflicts: $ spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java $ spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java
Thank you for the extended explanation. The original application (which was attached in a zip) does not use such a custom getter, so the fix that you propose should work out fine. It's been a while, but I believe the reason why I added a In our actual production applications, this is not a concern, since only the REST API is part of the public API. |
Uh oh!
There was an error while loading. Please reload this page.
Minimal reproduction example
Given a simple project with a JPA entity having a relation to an other JPA entity, both with exported repositories.
Normally, when creating and updating (POST/PUT) an entity via the REST endpoints, you can use the URL of the relation target.
(e.g.: send
{"package": "/packages/1"}
whenpackage
is a JPA@OneToOne
relation)However, this does not work when the JPA relation is annotated with
@JsonProperty()
to change the serialized name.JPA entity setup
When we retrieve the JSON-schema for `Product`, it specifies a property named `package` that is of string/URL type
However, when creating the entity following the JSON schema, we receive an error:
Analysis
We were able to trace the difference between a renamed and non-renamed JSON property to this line:
spring-data-rest/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java
Line 447 in 6030f85
The issue at hand is that
property.getName()
returns the name of the property in JSON/serialized format.In simple cases, this matches with the name of the
PersistentProperty
as expected byentity.getPersistentProperty()
.But when a field is given a different serialized name with
@JsonProperty
, noPersistentProperty
for that name can be found, resulting in no custom deserializer being installed for that property.Related issues
I found a couple issues that seem to have the same cause:
Reproducer application
acc-296.zip
This is a spring-boot application using spring-data-rest.
./gradlew bootRun
in the project.curl http://localhost:8080/packages -XPOST -d '{}' -H 'Content-type: application/json'
_links.self.href
to create a product:curl http://localhost:8080/products -XPOST -d '{"package": "http://localhost:8080/packages/f34c136f-3004-4908-aa19-169d4b086da0" }' -H 'Content-type: application/json'
You can also perform the same operations from HAL explorer, entering the package URL in the
_package
form field, which generates the same{"package": "...."}
JSONTestcase
I added a failing test (and a passing test for the functionality that did not seemed to be covered) in my fork: 3.7.x...vierbergenlars:spring-data-rest:fix-renamed-linkable-assocs
The text was updated successfully, but these errors were encountered: