I'm testing out Spring Boot 4 RC1 for an app I'm working on and ran into a serialization issue. I have a Draft that has an id and a json object stored as JSONB in a Postgres db. In Spring Boot 3 with Jackson 2 this works perfectly fine, the data I get out is the same data that is in the database.
However, when I upgraded to Spring Boot 4 and Jackson 3, I no longer get the correct data out from the controller. It appears to return the metadata from the JsonNode instead of the actual data.
I created a small demo app that demonstrates issue. One test is just the service that fetches from database, that isOK. Second test is calling the Controller. And then the data is wrong. https://github.com/tGrefsrud/demo-spring-boot-4-serialization-issue
Expected output from the test: {"message":"Hello World"} Actual output: {"array":false,"bigDecimal":false,"bigInteger":false,"binary":false,"boolean":false,"containerNode":true,"double":false,"empty":false,"float":false,"floatingPointNumber":false,"int":false,"integralNumber":false,"long":false,"missingNode":false,"nodeType":"OBJECT","null":false,"number":false,"object":true,"pojo":false,"short":false,"textual":false,"valueNode":false}
I'm unsure if this is a Spring Boot issue or a Jackson issue, but I figured I'd go here first.
Comment From: bclozel
Your Draft object contains a com.fasterxml.jackson.databind.JsonNode field. Is that expected? I don't think Jackson 3 supports this type. Can you try with tools.jackson.databind.JsonNode instead?
Comment From: tGrefsrud
@bclozel With tools.jackson.databind.JsonNode I get the following error:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of tools.jackson.databind.JsonNode (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 1]
Which may be due to JsonNode being abstract here? Using tools.jackson.databind.ObjectNode instead gives an error conflicting setter definitons:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Conflicting setter definitions for property "all": tools.jackson.databind.node.ObjectNode#setAll(java.util.Map) vs tools.jackson.databind.node.ObjectNode#setAll(tools.jackson.databind.node.ObjectNode)
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
Comment From: bclozel
I've just sent a PR to your repository.
I think there are a few issues here: * first, Flyway brings Jackson 2 transitively and this is hiding the fact that you should consider upgrading your application to Jackson 3. * Hibernate supports JSON serialization to the database using Jackson 2.x but does not support Jackson 3 at the moment. Can you check if their issue tracker has a relevant issue or create a new one for this?
In the meantime, my PR adopts Jackson 3 in your application and configures a custom JacksonJsonFormatMapper that does this for you. With that in mind, I don't think there is much we can do in Spring Boot to improve the situation so I'm closing this issue. We can reopen if we find a way to help with this.
Thanks a lot for testing our RC1, this is valuable feedback.
Comment From: tGrefsrud
Thanks, I'll check Hibernate's issue tracker as well.