Skip to content
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

JSON deserialization for Kotlin collections on inherited classes #24033

Closed
vb-dci opened this issue Nov 12, 2019 · 4 comments
Closed

JSON deserialization for Kotlin collections on inherited classes #24033

vb-dci opened this issue Nov 12, 2019 · 4 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: bug A general bug
Milestone

Comments

@vb-dci
Copy link

vb-dci commented Nov 12, 2019

I found a problem with json deserialization on lists with inherited classes and kotlin. The problem occurs when you define an abstract rest endpoint on kotlin collections.
Here's a small example:

abstract class BaseCrudController<Dto : BaseDto> {
    @PostMapping("/saveAll")
    @ResponseBody
    fun saveAsList(@RequestBody dtos: List<Dto>): List<Dto> = listOf()
}

@Controller
@RequestMapping("/api/v1/customer")
class CustomerController() : BaseCrudController<CustomerDto>()

Here's the class to deserialize:

class CustomerDto(var name: String?, var accountNumber: String?) : BaseDto()

abstract class BaseDto {
    var id: Long? = null
    var version: Int = 0
}

The error message is:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.example.basecrudspringrestendpoint.presentation.dto.core.BaseDto]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinition
Exception: Cannot construct instance of `com.example.basecrudspringrestendpoint.presentation.dto.core.BaseDto` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (PushbackInputStream); line: 2, column: 3] (through reference chain: java.util.ArrayList[0])] with root cause

according to a bug ticket in the jackson module, the problem is maybe that spring not passing type resolution context to jackson: FasterXML/jackson-module-kotlin#267

you can find the code for this also here https://github.com/vb-dci/jackson-spring-bug

@philwebb
Copy link
Member

Thanks for the report. The HttpMessageConverter is part of Spring Framework so I'll transfer this issue for that team to consider.

@philwebb philwebb transferred this issue from spring-projects/spring-boot Nov 19, 2019
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 19, 2019
@sdeleuze sdeleuze self-assigned this Nov 21, 2019
@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Nov 8, 2021
@sdeleuze sdeleuze added the theme: kotlin An issue related to Kotlin support label Jan 19, 2022
@sdeleuze
Copy link
Contributor

sdeleuze commented Feb 8, 2023

Hi, sorry for the delay. I can still reproduce with Spring Boot 3.0.2.

@jhoeller Looks like a potential type caching issue in ResolvableType#forType(Type, TypeProvider, VariableResolver), see attached screenshot. The generic parameter seems wrongly considered as fully resolved due to another entry returned from the cache, making ResolvableType#hasUnresolvableGenerics return false, and skipping the resolution of the generic type from the contextClass.

Screenshot from 2023-02-08 10-18-03

@sdeleuze sdeleuze added this to the 6.0.6 milestone Feb 8, 2023
@sdeleuze sdeleuze added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 8, 2023
@jhoeller jhoeller changed the title json desirialization for kotlin collections on inheritated classes JSON deserialization for Kotlin collections on inherited classes Feb 14, 2023
@sdeleuze sdeleuze modified the milestones: 6.0.6, 6.0.7 Mar 1, 2023
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Mar 6, 2023
Before this commit, Spring MVC was unable to resolve upper or lower
bounds on Spring MVC request body parameter when generic controller
inheritance was involved. This use case is common with Kotlin
which uses declaration-site variance for List<T>.

This commit adds a related GenericTypeResolver#resolveGenericBounds
used in HttpEntityMethodProcessor and RequestResponseBodyMethodProcessor
to resolve properly generic parameters.

Closes spring-projectsgh-24033
@sdeleuze
Copy link
Contributor

sdeleuze commented Mar 6, 2023

I have a related draft commit, we could maybe introduce related method in ResolvableType to return a type with resolved bounds. Let's try that as part of 6.1 early in the development cycle.

@sdeleuze
Copy link
Contributor

sdeleuze commented Jul 3, 2023

Fixed by f075120.

@sdeleuze sdeleuze closed this as completed Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants