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

Null coercion not working with property-based @JsonCreator #2024

Closed
cowtowncoder opened this issue May 4, 2018 · 3 comments
Closed

Null coercion not working with property-based @JsonCreator #2024

cowtowncoder opened this issue May 4, 2018 · 3 comments
Milestone

Comments

@cowtowncoder
Copy link
Member

(note: follow-up to #1402 for null coercion)

Although null coercion (and skipping, error reporting) works with fields, setters, it appears not to work as intended via Creator methods. Would be good if it did.
This occurs up to 2.9.5.

cowtowncoder added a commit that referenced this issue May 4, 2018
@cowtowncoder
Copy link
Member Author

Looks like problem is that PropertyMetadata is created differently for CreatorProperty; if setter/nulls info was available, empty/fail would work (skip has semantics that can not be supported with creator).
Fundamentally problem seems to be that construction of creator properties proceeds quite differently, and unfortunately full logic that POJOPropertyBuilder has, nicely encapsulated, can not be accessed for creator properties (unless there are matching fields, getters, in which case this probably works).

So. The place where this can be done is either in constructCreatorProperty() of BasicDeserializerFactory (explicitly introspect), or, possibly, in addBeanProps() of BeanDeserializerFactory (merge, as it seems that metadata does somehow exist?)

@sanyarnd
Copy link

sanyarnd commented Jun 25, 2019

The exact same issue still occurs with 2.9.9 when using lombok's @Value annotation, .setDefaultSetterInfo(...); call is ignored.

Currently there is a workaround (source):

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().registerModule(new SimpleModule().setDeserializerModifier(new NullCollectionsAsEmptyModifier()));

private static abstract class ContextualJsonDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer { }
private static class NullCollectionsAsEmptyModifier extends BeanDeserializerModifier {
	@Override
	public JsonDeserializer<?> modifyMapDeserializer(DeserializationConfig config, MapType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
		return new ContextualJsonDeserializer() {
			@Override
			public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
				return modifyMapDeserializer(config, type, beanDesc, ((ContextualDeserializer) deserializer).createContextual(ctxt, property));
			}

			@Override
			public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
				return deserializer.deserialize(p, ctxt);
			}

			@Override
			public Object getNullValue(DeserializationContext ctxt) {
				return Collections.emptyMap();
			}
		};
	}

	@Override
	public JsonDeserializer<?> modifyCollectionDeserializer(DeserializationConfig config, CollectionType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
		return new ContextualJsonDeserializer() {
			@Override
			public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
				return modifyCollectionDeserializer(config, type, beanDesc, ((ContextualDeserializer) deserializer).createContextual(ctxt, property));
			}

			@Override
			public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
				return deserializer.deserialize(p, ctxt);
			}

			@Override
			public Object getNullValue(DeserializationContext ctxt) {
				return Collections.emptyList();
			}
		};
	}
}

@cowtowncoder
Copy link
Member Author

I just fixed #2458 and I think these two were actually the same issue -- so although this is older, I think I'll close this as duplicate due to release notes adding fixing of the other issue.
Both fixed for 2.10.0.

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

No branches or pull requests

2 participants