jackson-module-kotlin icon indicating copy to clipboard operation
jackson-module-kotlin copied to clipboard

Way to ignore properties from delegate

Open vladokvocka opened this issue 4 years ago • 6 comments

Hi, consider following code:

data class Base(
    @JsonProperty("prop1") val prop1: String,
    @JsonProperty("prop2") val prop2: String
)

data class Specific(
    @JsonProperty("baseProps") val baseProps: Base,
    @JsonProperty("prop3") val prop3: String
) : Base by baseProps

When using objectMapper.writeValueAsString(specific), result JSON looks like this:

{
    "@type": "Specific",
    "baseProps": {
        "@type": "Base",
        "prop1": "value1",
        "prop2": "value2"
    },
    "prop1": "value1",
    "prop2": "value2",
    "prop3": "value3"
}

Is there a way to ignore all delegated properties from delegate Base without specifying every one of them using @JsonIgnoreProperties? Something like @JsonIgnoreDelegates("baseProps") would be great. The result should look like this:

{
    "@type": "Specific",
    "baseProps": {
        "@type": "Base",
        "prop1": "value1",
        "prop2": "value2"
    },
    "prop3": "value3"
}

vladokvocka avatar Jun 02 '21 14:06 vladokvocka

Interesting idea, I think that we'd be able to do that with some changes in KotlinNamesAnnotationIntrospector.

dinomite avatar Jun 05 '21 10:06 dinomite

I would recommend caution wrt adding such logic in AnnotationIntrospector as it would sort of have to undo/redo quite a bit of logic to recreate inheritance hierarchy (or other processing to do cross-type introspection). The main challenge is that AI is designed to be called on property-by-property basis which makes it difficult to do changes based on a set of properties.

It does sound something that would not necessarily Kotlin-specific (if I understand this correctly), so it could possibly be in databind.

One other thing to consider for now is that @JsonIncludeProperties would be little bit less work, to allow specifying only properties that are to be included.

cowtowncoder avatar Jun 07 '21 01:06 cowtowncoder

The limitations on Kotlin make it very difficult to fix this problem. The details are summarized in the following comment. https://github.com/FasterXML/jackson-module-kotlin/issues/574#issuecomment-1473725622

If the following is implemented in Jackson, this problem may be solved. https://github.com/FasterXML/jackson-future-ideas/issues/28

k163377 avatar Apr 04 '23 14:04 k163377

In response to comment from @sandwwraith, I have reviewed this issue again.

As for the requested feature, unfortunately I don't think it is important enough to introduce it into kotlin-module.

First of all, we have had a long time so far, and there does not seem to be a lot of support for this feature request. Also, since there are not that many classes that would be defined this way, I think that customization using MixIn would be sufficient.

import com.fasterxml.jackson.annotation.JsonIgnore
import org.junit.jupiter.api.Test

interface I {
    val i: Int
}

data class Delegated(val p: I) : I by p

abstract class MixIn : I {
    @get:JsonIgnore
    abstract override val i: Int
}

class Temp {
    @Test
    fun test() {
        val dto = Delegated(object : I { override val i: Int = 1 })
        val mapper = jacksonObjectMapper().addMixIn(Delegated::class.java, MixIn::class.java)
        println(mapper.writeValueAsString(dto)) // -> {"p":{"i":1}}
    }
}

k163377 avatar Mar 16 '24 05:03 k163377

I agree that the feature would need to be implemented in jackson-databind so filing an issue there would make sense. Not saying it would be likely to be implemented (this would be tricky to do), but that'd be the place.

cowtowncoder avatar Mar 21 '24 01:03 cowtowncoder