Serialization: Preserving object identities?

I’m just starting with the topic serialization and wonder whether/how I can serialize my objects storing references (preserving objet identities) and not storing object copies. I use kotlinx.serialization.

For example, I have a class B which stores a list of instances of A.

@Serializable
data class A(val name: String)

@Serializable
data class B(val name: String) {
    val listOfAs = mutableListOf<A>()
}

I can now, lets say, create two instances of B (b1 and b2) which both add a reference to one instance of A (a). I can serialize the objects:

val json = Json(JsonConfiguration.Stable)
val a = A("XXX")

val b1 = B("B1")
b1.myA.add(a)
val b2 = B("B2")
b2.myA.add(a)

val jsonData = json.stringify(B.serializer().list, listOf(b1, b2))

But when I deserialize the data, I don’t get one (!) instance of A but two. That is, my instances of B both reference their own instance of A.

val myBs = json.parse(B.serializer().list, jsonData)

So I wonder if it is possible to preserve the object identities somehow? (And I hope that the problem description is clear. :slight_smile: )

Short answer: that’s not possible out of the box.

Long answer: in your example there are multiple levels of abstraction that do not support what you need.

It starts with the fact that json does not know about object identities. You would need to encode the identity information into your objects yourself, for example with some custom id property.

That’s not enough though, as out of the box this id property will not be used by kotlinx-serialization for object identities. You would need to configure your own serializer which will reuse objects when they already exist for a given id, for example by using a weakhashmap object pool.

1 Like