Skip to content

Deserialization doesn't handle null values correctly when a kotlin value class is present #656

Closed
@roskh

Description

@roskh

Describe the bug
When a kotlin data class has a value object as part of it's parameters the non-null checks usually performed by jackson are not done.

To Reproduce

Here's a minimal test file. I'm using JacksonAutoConfiguration from spring boot to automatically load the correct jackson modules but I still think the error is due to this lib.
Let me know if this issue is incorrect or is more appropriate in another project.

package jacksontest

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ContextConfiguration
import java.time.LocalDateTime

@JvmInline
value class ValueClass(val value: String)

data class Correct(
    val notNull: LocalDateTime,
    val fields: List<ValueClass>
)

data class Incorrect(
    val notNull: LocalDateTime,
    val field: ValueClass
)

@ContextConfiguration(classes = [JacksonAutoConfiguration::class])
@SpringBootTest
class ValueClassJacksonTest {
    @Autowired
    lateinit var mapper: ObjectMapper

    @Test
    fun `value class inside collection should not affect outer class nullability`() {
        val json = """
            {
                "notNull": null,
                "fields": []
            }
        """.trimIndent()

        assertThrows<MissingKotlinParameterException> {
            mapper.readValue(json, Correct::class.java)
        }
    }

    // test fails
    @Test
    fun `value class should not affect outer class nullability`() {
        val json = """
            {
                "notNull": null,
                "field": "a"
            }
        """.trimIndent()

        assertThrows<MissingKotlinParameterException> {
            val obj = mapper.readValue(json, Incorrect::class.java)
            println(obj)
        }
    }
}

Expected behavior
Second test case should not fail

Versions
Kotlin: 1.8.10
Jackson-module-kotlin: 2.14.2
Jackson-databind: 2.14.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions