spring-projects / spring-projects/spring-data-rest

DomainClassConverter only works with ID, not custom lookup [DATAREST-1229]

Open
#1,588 0 comments 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 31, 2020.

type: enhancement
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.