Skip to content

JsonKeysetCursorStrategy does not support java.util.UUID in keysets #1327

@heruan

Description

@heruan

When using Relay-style cursor pagination with ScrollSubrange, cursors fail to round-trip when the keyset contains a java.util.UUID (e.g., when sorting by an entity id of type UUID). The cursor can be produced, but decoding back to a keyset does not restore the UUID value because it is not handled among the supported scalar types.

Relevant implementation area:

PolymorphicTypeValidator validator = BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(Map.class)
.allowIfSubType("java.time.")
.allowIfSubType(Calendar.class)
.allowIfSubType(Date.class)
.build();

Example code to reproduce:

@Entity
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;

    private String name;
}

@Controller
public class AuthorController {

    private final AuthorRepository authorRepository;

    AuthorController(AuthorRepository authorRepository) {
        this.authorRepository = authorRepository;
    }

    @QueryMapping
    Window<Author> authors(ScrollSubrange subrange) {
        var position = subrange.position().orElseGet(ScrollPosition::keyset);
        var limit = Limit.of(subrange.count().orElse(10));
        var sort = Sort.by(Sort.Direction.ASC, "id", "name");
        return authorRepository.findAll(position, limit, sort);
    }
}

Then a query with a cursor such as:

query Authors {
  authors(first: 10, after: "S19bImphdmEudXRpbC5Db2xsZWN0aW9ucyRVbm1vZGlmaWFibGVNYXAiLHsiaWQiOlsiamF2YS51dGlsLlVVSUQiLCJlYzdlNzJmYy0xOTFjLTQyODgtYjNlYS03ZjRjZTQ4MDBiOTgiXSwibmFtZSI6IlAuIFB1bGxtYW4ifV0") {
    edges {
      node {
        name
      }
    }
}

fails with:

java.lang.IllegalArgumentException: Failed to parse cursor: K_["java.util.Collections$UnmodifiableMap",{"id":["java.util.UUID","ec7e72fc-191c-4288-b3ea-7f4ce4800b98"],"name":"P. Pullman"}]
	at org.springframework.graphql.data.query.ScrollPositionCursorStrategy.fromCursor(ScrollPositionCursorStrategy.java:92) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.query.ScrollPositionCursorStrategy.fromCursor(ScrollPositionCursorStrategy.java:34) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.pagination.EncodingCursorStrategy.fromCursor(EncodingCursorStrategy.java:77) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.method.annotation.support.SubrangeMethodArgumentResolver.resolveArgument(SubrangeMethodArgumentResolver.java:66) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.method.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:82) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.method.annotation.support.DataFetcherHandlerMethodSupport.getMethodArgumentValues(DataFetcherHandlerMethodSupport.java:92) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.method.annotation.support.DataFetcherHandlerMethod.invoke(DataFetcherHandlerMethod.java:121) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.method.annotation.support.DataFetcherHandlerMethod.invoke(DataFetcherHandlerMethod.java:107) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
Caused by: org.springframework.core.codec.DecodingException: JSON decoding error: Could not resolve type id 'java.util.UUID' as a subtype of `java.lang.Object`: Configured `PolymorphicTypeValidator` (of type `tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator`) denied resolution
	at org.springframework.http.codec.AbstractJacksonDecoder.processException(AbstractJacksonDecoder.java:268) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
	at org.springframework.http.codec.AbstractJacksonDecoder.decode(AbstractJacksonDecoder.java:205) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
	at org.springframework.graphql.data.query.JsonKeysetCursorStrategy.fromCursor(JsonKeysetCursorStrategy.java:142) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.query.JsonKeysetCursorStrategy.fromCursor(JsonKeysetCursorStrategy.java:60) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]
	at org.springframework.graphql.data.query.ScrollPositionCursorStrategy.fromCursor(ScrollPositionCursorStrategy.java:87) ~[spring-graphql-2.0.0-M3.jar:2.0.0-M3]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions