You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug or feature request: Documentation isn't clear enough to me to make that distinction, so I'll leave the label up to you.
Versions tested: 2.12.4, 2.13.0.
I'm converting some of the IDs in my data payloads to typed IDs instead of simple Strings to improve my code readability and to differentiate the different types of IDs I have in my code base. It seems like having a class with a singular @JsonValue member as below is perfect for that as a drop-in replacement for String values (and there will be identical but differently named classes for the other IDs).
Sometimes my ID in JSON are empty strings, and sometimes they are null, due to other-party constraints. I want to deserialize both of those as null instead of TypedId("") or TypedId(null) in the Java code, to avoid the confusing case of having a non-null TypeId object which itself does not have a valid ID.
It seems that Jackson has a DeserializationFeature for this called ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, however it does not seem to work in this use-case.
Here's the containing class for my minimum example demonstrating this behavior:
publicclassContainer {
@JsonPropertypublicTypedIdid;
// @JsonProperty// ... other properties
}
Here are the three test cases I constructed that should succeed according to my expectation, but the second test case fails:
/** Test that non-empty string IDs are correctly deserialized as TypedId classes with the passed ID. */@TestpublicvoidtestNonEmptyStringId() throwsJsonProcessingException {
ObjectMapperobjectMapper = newObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
Containervalue = objectMapper.readValue("{\"id\": \"1234-abcd\"}", Container.class);
assertEquals(newTypedId("1234-abcd"), value.id); // succeeds
}
/** Test that empty strings are treated as null objects, and no TypedId is constructed with the empty string. */@TestpublicvoidtestEmptyStringId() throwsJsonProcessingException {
ObjectMapperobjectMapper = newObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
Containervalue = objectMapper.readValue("{\"id\": \"\"}", Container.class);
assertNull(value.id); // fails, value.id = TypedId(""), not null.
}
/** Test that passing a null value does not construct a TypedId class with a null ID but instead leaves the Container member null. */@TestpublicvoidtestNullId() throwsJsonProcessingException {
ObjectMapperobjectMapper = newObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
Containervalue = objectMapper.readValue("{\"id\": null}", Container.class);
assertNull(value.id); // succeeds
}
The second test fails as Jackson constructs a TypedId class with an empty string despite enabling the deserialization feature to prevent this, which I believe is either a bug, or I would like to request a feature to deal with this specific case.
The text was updated successfully, but these errors were encountered:
Could anyone have a look whether this is a bug, or whether it's a use-case that might require a separate DeserializationFeature?
If a workaround is known for this scenario, that would also be appreciated!
I'm willing to look into fixing the bug or adding the feature myself, if someone can give me some pointers where to look.
This may be due to documentation, but ACCEPT_EMPTY_STRING_AS_NULL_OBJECT does not mean forced coercion from empty String into target type, in cases where there is valid handling already in place. @JsonValue, for its part, will happily take any String, pass it to @JsonCreator annotated constructor and so on.
So as far as I can see it works as I'd expect to -- I realize this may not be what you'd like to happen.
I would not try to change semantics here for DeserializationFeature.
What you can (and probably need to do) is to create factory method for TypeId, in which you will add special handling for case of empty String. Explicit JSON null will be handled automatically and they will not go via creator method.
Bug or feature request: Documentation isn't clear enough to me to make that distinction, so I'll leave the label up to you.
Versions tested: 2.12.4, 2.13.0.
I'm converting some of the IDs in my data payloads to typed IDs instead of simple Strings to improve my code readability and to differentiate the different types of IDs I have in my code base. It seems like having a class with a singular
@JsonValue
member as below is perfect for that as a drop-in replacement for String values (and there will be identical but differently named classes for the other IDs).Sometimes my ID in JSON are empty strings, and sometimes they are
null
, due to other-party constraints. I want to deserialize both of those asnull
instead ofTypedId("")
orTypedId(null)
in the Java code, to avoid the confusing case of having a non-null TypeId object which itself does not have a valid ID.It seems that Jackson has a
DeserializationFeature
for this calledACCEPT_EMPTY_STRING_AS_NULL_OBJECT
, however it does not seem to work in this use-case.Here's the containing class for my minimum example demonstrating this behavior:
Here are the three test cases I constructed that should succeed according to my expectation, but the second test case fails:
The second test fails as Jackson constructs a TypedId class with an empty string despite enabling the deserialization feature to prevent this, which I believe is either a bug, or I would like to request a feature to deal with this specific case.
The text was updated successfully, but these errors were encountered: