spring-projects / spring-projects/spring-data-rest
DomainClassConverter only works with ID, not custom lookup [DATAREST-1229]
@odrotbohm is already working on this.
Since Dec 31, 2020.
- Dominant language
- Java
- Stars
- 958
- Forks
- 568
- PR merge metrics
- No merged PRs in 30d
Description
Abhinav Sonkar opened DATAREST-1229 and commented
EDIT
Ok, I did some debugging and found that the DomainClassConverter already supports custom entity lookup. That's how the PUT method on association resource works by automatically converting my custom UUID into the right entity.
In my RepositoryRestController, I am using a @PathVariable with an entity and a corresponding Spring Data Repository. But instead of automatically converting the "id" into entity object, it is failing with MethodArgumentTypeMismatchException and underlying exception is NumberFormatException as it expects a Long instead of a String. Debugging through the code, I can verify that the UriToEntityConverter is never called.
@RepositoryRestController
@RequestMapping("/application_access/{id}")
public class StreamAuthorizationController {
@RequestMapping(method = RequestMethod.GET, value = "/authorizations")
public ResponseEntity<?> getAuthorizations(@PathVariable("id") ApplicationAccess uid) {
...
}
In the code above, the ApplicationAccess entity is not being generated automatically from the "id" variable.
When using PathVariable in a Controller method with an entity, the default behaviour of DomainClassConverter is to generate the entity from the ID. This works perfectly when using the same ID in REST URIs but unfortunately stops working if a custom field is used for entity lookup.
Here is an example of a custom entity lookup config which uses a UUID instead of default Long:
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
// Use UUID instead of primary key id as REST lookup
config.withEntityLookup()
.forRepository(ApplicationAccessRepository.class, ApplicationAccess::getUid, ApplicationAccessRepository::findByUid)
With above configuration in place, the DomainClassConverter fails to convert the ID to an entity with a NumberFormatException as it is unable to convert a string UUID into a Long based ID.
Caused by: java.lang.NumberFormatException: For input string: "asvascasc"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_144]
at java.lang.Long.parseLong(Long.java:589) ~[na:1.8.0_144]
at java.lang.Long.valueOf(Long.java:803) ~[na:1.8.0_144]
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:62) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:49) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
... 102 common frames omitted
Is it possible to extend DomainClassConverter to correctly identify the right converter based on the entity lookup? If not, what would be an alternative solution? Thanks!
No further details from DATAREST-1229
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.