Skip to content

QueryDSL: Jackson serialization with Spring Pagable and QSort applied #2676

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

Closed
cswan-log opened this issue Aug 17, 2022 · 1 comment
Closed
Labels
status: duplicate A duplicate of another issue

Comments

@cswan-log
Copy link

Getting data via a queryDSL repository with a pagable applied and a specific QSort order returns the desired result. Feeding it back to a rest controller endpoint will result in an exepection thrown by jackson because of a cyclic dependency in the sort path:

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.querydsl.core.types.Path<java.lang.Object>]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: org.springframework.data.domain.PageImpl["pageable"]->org.springframework.data.domain.PageRequest["sort"]->org.springframework.data.querydsl.QSort["orderSpecifiers"]->java.util.Arrays$ArrayList[0]->com.querydsl.core.types.OrderSpecifier["target"]->com.querydsl.core.types.PathImpl["metadata"]->com.querydsl.core.types.PathMetadata["parent"]->my.package.model.QMyEntity["created"]->com.querydsl.core.types.dsl.DateTimePath["root"]->com.querydsl.core.types.PathImpl["root"])

Steps to reproduce

  • Spring Project with QueryDSL and Jackson configured
  • Create an entity and a repository with QueryDSL support
  • Add a rest controller with the following code:
return repository.findAll(PageRequest.of(0, 10, QSort.by(QMyEntity.created.asc())))

To work around this error, you can supply some custom jackson mixins to avoid the serialization of specific fields:
Kotlin Code

@Suppress("unused")
abstract class PathMetadataMixin {
    @JsonIgnore
    abstract fun getParent(): Path<*>?

    @JsonIgnore
    abstract fun getRootPath(): Path<*>?
}

@Suppress("unused")
abstract class PathMixin {
    @JsonIgnore
    abstract fun getRoot(): Path<*>?

    @JsonIgnore
    abstract fun getAnnotatedElement(): AnnotatedElement?
}

// ...

@Bean
@Primary
fun objectMapper(): ObjectMapper {
    // builder is injected
    return jackson2ObjectMapperBuilder.createXmlMapper(false)
        .mixIn(PathMetadata::class.java, PathMetadataMixin::class.java)
        .mixIn(Path::class.java, PathMixin::class.java)
        .build()
}

This is obviously only a valid workaround when you are using jackson within your project. A general purpose solution should be preferred.


Using Spring Boot 2.6.6 with spring-boot-starter-data-jpa and QueryDSL 5.0.0

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 17, 2022
@mp911de
Copy link
Member

mp911de commented Aug 17, 2022

Our Page and Sort objects are not intended to be used for Jackson serialization directly. Duplicates #1219, #1683

@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Aug 17, 2022
@mp911de mp911de added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants