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

595: Fix resource serialization #596

Merged

Conversation

belosh59
Copy link
Contributor

@belosh59 belosh59 commented Apr 17, 2024

The include = JsonTypeInfo.As.EXISTING_PROPERTY configuration for @JsonTypeInfo in Jackson specifies how type information—used for polymorphic type handling—is included in the serialized JSON. Let's delve into what this specific configuration means and how it compares to other available options.

JsonTypeInfo.As.EXISTING_PROPERTY

When you annotate a class with @JsonTypeInfo and use include = JsonTypeInfo.As.EXISTING_PROPERTY, Jackson is instructed to use an existing property on your Java object to include the type information necessary for deserialization. The property parameter of @JsonTypeInfo specifies the name of this property. This means:

  • During Serialization: Jackson does not add any additional property for type information. Instead, it expects the type information to be part of an existing property in your serialized JSON.
  • During Deserialization: Jackson looks at the specified property within the JSON to determine the type information necessary for instantiating the correct subclass.

This option is particularly useful when your JSON already contains a field that dictates the type but you don't want to introduce additional fields for type handling.

Other JsonTypeInfo.As Configurations

Jackson provides several ways to include type information in your JSON, catering to different JSON structures and requirements:

  1. PROPERTY (default): Adds type information as a separate property at the same level as other properties of the object. This is the most commonly used approach when you can modify the JSON structure to include type metadata.

  2. WRAPPER_OBJECT: Wraps the serialized object in another JSON object where the field name is the type information, and the value is the original object. This is useful when you want to keep the JSON structure clean without mixing type information with actual data fields.

  3. WRAPPER_ARRAY: Serializes the object into a JSON array where the first element is the type information and the second element is the actual object. Similar to WRAPPER_OBJECT, this keeps type information separate but uses an array structure.

  4. EXTERNAL_PROPERTY: Puts the type information in an external property, typically at the same level as the serialized object. This is useful in cases where you have a JSON object with multiple fields needing polymorphic type handling and you want to centralize the type information.

  5. EXISTING_PROPERTY: As described, expects the type information to be part of an existing property in the serialized JSON, avoiding the addition of extra fields for type handling.

Each of these configurations serves different use cases depending on how you wish to structure your JSON and manage type information for polymorphism. The choice depends on your specific requirements for serialization and deserialization, as well as the structure of your JSON data.

@@ -23,9 +23,10 @@
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import io.openraven.magpie.data.utils.EntityTypeResolver;

@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.PROPERTY, property = "resourceType")
@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "resourceType")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With value PROPERTY we were getting two resourceType in serialized string:

if (object instanceof Resource) {
return ((Resource) object).getResourceType();
}
return aClass.getName();
Copy link
Contributor Author

@belosh59 belosh59 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously under Jackson version 2.13.5 by returning null here and include = JsonTypeInfo.As.PROPERTY we were getting following.:
(Pay attention into two resourceType that is how PROPERTY include works)

{"resourceType":"null",
"resourceType":"AWS::RDS::DBInstance",
"documentId":null,
"arn":null,"resourceName":null,"resourceId":null,"awsRegion":null,"awsAccountId":null,"createdIso":null,"updatedIso":null,"discoverySessionId":null,"maxSizeInBytes":null,"sizeInBytes":null,"configuration":null,"supplementaryConfiguration":null,"tags":null,"discoveryMeta":null}

Now Jackson 2.15.4 doesn't allow to set null to resolving id and we were getting mentioned expection:

com.fasterxml.jackson.databind.JsonMappingException: Can not write a field name, expecting a value (through reference chain: io.openraven.magpie.data.aws.rds.RDSInstance["resourceType"])

With above fix we are getting now.

{"resourceType":"AWS::RDS::DBInstance",
"resourceType":"AWS::RDS::DBInstance",
"documentId":null,"arn":null,
"resourceName":null,"resourceId":null,"awsRegion":null,"awsAccountId":null,"createdIso":null,"updatedIso":null,"discoverySessionId":null,"maxSizeInBytes":null,"sizeInBytes":null,"configuration":null,"supplementaryConfiguration":null,"tags":null,"discoveryMeta":null}

When we set include = JsonTypeInfo.As.EXISTING_PROPERTY we are getting not getting resourceType duplicates:

{"resourceType":"AWS::RDS::DBInstance",
"documentId":null,"arn":null,
"resourceName":null,"resourceId":null,"awsRegion":null,"awsAccountId":null,"createdIso":null,"updatedIso":null,"discoverySessionId":null,"maxSizeInBytes":null,"sizeInBytes":null,"configuration":null,"supplementaryConfiguration":null,"tags":null,"discoveryMeta":null}

@belosh59 belosh59 merged commit b75dc0d into main Apr 18, 2024
2 checks passed
@kickroot kickroot deleted the 595-bug-unable-to-serialize-resource-after-jackson-upgrade branch April 18, 2024 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: unable to serialize Resource after Jackson upgrade
2 participants