Mulgard
Mulgard

Reputation: 10589

Kotlin inheritance: Objects are not equal after serialization and deserialization to / from json

I have kotlin classes with inheritance:

abstract class Classification(
        val accuracy: Double
)
@Document
class OrderForm(
        @Id
        val id: String,
        accuracy: Double,
        val customerNumber: String,
        val orders: List<Order>
) : Classification(accuracy)

And I implemented a serialization test:

internal class OrderFormTest : Logging {

    private val objectMapper = ObjectMapper().registerKotlinModule()

    @Test
    fun canBeSerialisedToJsonAndBack() {
        val expected = OrderForm(
                "123_ID",
                94.77,
                "123_CUSTOMER",
                listOf(
                        Order(
                                0.0,
                                OrderNumber(
                                        10.0,
                                        123456789L),
                                OrderSize(
                                        99.99,
                                        "38/40"),
                                OrderAmount(
                                        100.0,
                                        7),
                                OrderPrice(
                                        50.0,
                                        999.99),
                                OrderPage(
                                        23.29343,
                                        100)
                        ),
                        Order(
                                0.0,
                                OrderNumber(
                                        10.0,
                                        123456789L),
                                OrderSize(
                                        99.99,
                                        "38/40"),
                                OrderAmount(
                                        100.0,
                                        7),
                                OrderPrice(
                                        50.0,
                                        999.99),
                                OrderPage(
                                        23.29343,
                                        100)
                        )
                )
        )

        logger.info("expected: $expected")

        val json = objectMapper.writeValueAsString(expected)

        logger.info("json: $json")

        val result: OrderForm = objectMapper.readValue(json)

        logger.info("result: $result")

        val json2 = objectMapper.writeValueAsString(result);

        logger.info("json: $json2")

        Assertions.assertThat(result).isEqualTo(expected)
    }
}

Log output:

14:57:37.031 [main] OrderFormTest - expected: de.fronetic.witt.ml.backend.model.OrderForm@4b34fff9
14:57:37.623 [main] OrderFormTest - json: {"id":"123_ID","accuracy":94.77,"customerNumber":"123_CUSTOMER","orders":[{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}},{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}}]}
14:57:37.673 [main] OrderFormTest - result: de.fronetic.witt.ml.backend.model.OrderForm@38b972d7
14:57:37.674 [main] OrderFormTest - json: {"id":"123_ID","accuracy":94.77,"customerNumber":"123_CUSTOMER","orders":[{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}},{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}}]}

So the content of the objects is exactly the same but the objects itself are not equal!

If I do not use inheritance this is not happening:

@Document
data class OrderForm(
        @Id
        val id: String,
        val accuracy: Double,
        val customerNumber: String,
        val orders: List<Order>
)

Log output:

14:59:03.889 [main] OrderFormTest - expected: OrderForm(id=123_ID, accuracy=94.77, customerNumber=123_CUSTOMER, orders=[Order(accuracy=0.0, orderNumber=OrderNumber(accuracy=10.0, number=123456789), orderSize=OrderSize(accuracy=99.99, size=38/40), orderAmount=OrderAmount(accuracy=100.0, amount=7), orderPrice=OrderPrice(accuracy=50.0, price=999.99), orderPage=OrderPage(accuracy=23.29343, page=100)), Order(accuracy=0.0, orderNumber=OrderNumber(accuracy=10.0, number=123456789), orderSize=OrderSize(accuracy=99.99, size=38/40), orderAmount=OrderAmount(accuracy=100.0, amount=7), orderPrice=OrderPrice(accuracy=50.0, price=999.99), orderPage=OrderPage(accuracy=23.29343, page=100))])
14:59:04.833 [main] OrderFormTest - json: {"id":"123_ID","accuracy":94.77,"customerNumber":"123_CUSTOMER","orders":[{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}},{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}}]}
14:59:04.913 [main] OrderFormTest - result: OrderForm(id=123_ID, accuracy=94.77, customerNumber=123_CUSTOMER, orders=[Order(accuracy=0.0, orderNumber=OrderNumber(accuracy=10.0, number=123456789), orderSize=OrderSize(accuracy=99.99, size=38/40), orderAmount=OrderAmount(accuracy=100.0, amount=7), orderPrice=OrderPrice(accuracy=50.0, price=999.99), orderPage=OrderPage(accuracy=23.29343, page=100)), Order(accuracy=0.0, orderNumber=OrderNumber(accuracy=10.0, number=123456789), orderSize=OrderSize(accuracy=99.99, size=38/40), orderAmount=OrderAmount(accuracy=100.0, amount=7), orderPrice=OrderPrice(accuracy=50.0, price=999.99), orderPage=OrderPage(accuracy=23.29343, page=100))])
14:59:04.914 [main] OrderFormTest - json: {"id":"123_ID","accuracy":94.77,"customerNumber":"123_CUSTOMER","orders":[{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}},{"accuracy":0.0,"orderNumber":{"accuracy":10.0,"number":123456789},"orderSize":{"accuracy":99.99,"size":"38/40"},"orderAmount":{"accuracy":100.0,"amount":7},"orderPrice":{"accuracy":50.0,"price":999.99},"orderPage":{"accuracy":23.29343,"page":100}}]}

Why is this happening?

Upvotes: 0

Views: 554

Answers (1)

Joffrey
Joffrey

Reputation: 37720

The problem is not inheritance VS absence of inheritance per se.

In one case you're using a data class (which automatically generates the equals() method) and in the other you're using a standard class, which does not have any magic.

In the standard classes, you need to implement equals() yourself (or generate it with the help of your IDE).

Upvotes: 5

Related Questions