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

Using delegated properties in deserialization #574

Closed
StefanSrf opened this issue Jul 12, 2022 · 4 comments
Closed

Using delegated properties in deserialization #574

StefanSrf opened this issue Jul 12, 2022 · 4 comments
Labels

Comments

@StefanSrf
Copy link

StefanSrf commented Jul 12, 2022

Your question
We would like to make use of kotlins 'inheritance by delegation' feature. In the json-structure the object should be flat, i.e. not exposing the delegation. Suppressing the delegation during serialization works, but deserialization fails. Is there a way to achive this or should we raise a feature request?

Example:

class DelegateTest {
    interface SharedInterface {
        val commonString: String
    }

    data class InternalSharedDelegate(override val commonString: String) : SharedInterface

    data class ExposedObject(
        // ignore/hide the delegation in json serialization
        @param:JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
        val delegate: InternalSharedDelegate,
        val otherValue: String
    ) : SharedInterface by delegate

    private val objectMapper = jsonMapper { addModule(kotlinModule()) }

    @Test
    fun `should deserialize delegated property`() {
        val exposedObject = ExposedObject(delegate = InternalSharedDelegate("a"), otherValue = "b")

        val serialized = objectMapper.writeValueAsString(exposedObject)
        assertEquals("{\"otherValue\":\"b\",\"commonString\":\"a\"}", serialized)

        // following line causes:
        // Instantiation of [simple type, class DelegateTest$ExposedObject] value failed for JSON property delegate due to missing (therefore NULL) value for creator parameter delegate which is a non-nullable type
        val deserialized: ExposedObject = objectMapper.readValue(serialized)

        assertEquals(exposedObject, deserialized)
    }
}
@k163377
Copy link
Contributor

k163377 commented Mar 17, 2023

First, it seems difficult to solve this with an approach as jackson-module-kotlin.

There doesn't seem to be any way to detect that a class is inheritance by delegation in kotlin-reflect.
I also checked kotlinx-metadata-jvm, but there seems to be no way to identify the property being used for the delegation.
https://github.com/JetBrains/kotlin/blob/master/libraries/kotlinx-metadata/src/kotlinx/metadata/Flag.kt

In other words, there is no way to get information to control serialization and deserialization.

I also checked Jackson features, but could only find unimplemented features.
FasterXML/jackson-future-ideas#28

@k163377
Copy link
Contributor

k163377 commented Apr 4, 2023

It is closed as a duplicate of #459.

@sandwwraith
Copy link

I was just passing by, but kotlinx-metadata-jvm has a way to determine if a declaration came from interface delegation: it is stored in the kind enum, e.g. kmProperty.kind == MemberKind.DELEGATION (using new API, old Flags API would look like Flags.Property.IS_DELEGATION(prop.flags)

@k163377
Copy link
Contributor

k163377 commented Mar 16, 2024

@sandwwraith
Thank you for your comment.
It does indeed seem to work, I may have misunderstood something.

However, I am not considering implementing this feature itself.
Please see my comment below for more details.
#459 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants