Skip to content

forValueNulls Introduced in Jackson 2.9 Ignored #356

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

Closed
neilchaudhuri opened this issue Dec 7, 2017 · 5 comments
Closed

forValueNulls Introduced in Jackson 2.9 Ignored #356

neilchaudhuri opened this issue Dec 7, 2017 · 5 comments

Comments

@neilchaudhuri
Copy link

Given this case class:

case class Value( @JsonSetter(nulls=Nulls.FAIL) offers: Map[String, Offer] = Map.empty[String, Offer] )

and this JSON:

{ "offers": null }

There is no failure on deserialization. I have also tried setting the value globally on ObjectMapper:

objectMapper.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.FAIL))

This doesn't work either.

Am I doing something wrong? Or is this a bug?

Thanks.

@maslovalex
Copy link

There is a problem with the JsonSetter annotation and CreatorProperties (constructor parameters).
offers here is the CreatorProperty and to be able to construct Value class every CreatorProperty of that class is deserialized mostly via SettableBeanProperty.deserialize(....)

public final Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
  if (p.hasToken(JsonToken.VALUE_NULL)) {
     return _nullProvider.getNullValue(ctxt);
  }
  if (_valueTypeDeserializer != null) {
    return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
  }
   return _valueDeserializer.deserialize(p, ctxt);
}

this is the invocation stack

CreatorProperty(SettableBeanProperty).deserialize(JsonParser, DeserializationContext) line: 523	
BeanDeserializer._deserializeWithErrorWrapping(JsonParser, DeserializationContext, SettableBeanProperty) line: 528	
BeanDeserializer._deserializeUsingPropertyBased(JsonParser, DeserializationContext) line: 417	
BeanDeserializer(BeanDeserializerBase).deserializeFromObjectUsingNonDefault(JsonParser, DeserializationContext) line: 1280	
BeanDeserializer.deserializeFromObject(JsonParser, DeserializationContext) line: 326	
BeanDeserializer.deserialize(JsonParser, DeserializationContext) line: 159	
ObjectMapper._readMapAndClose(JsonParser, JavaType) line: 4001	
ObjectMapper.readValue(String, TypeReference) line: 3011	

As you can see, when you have explicit null like in { "offers": null } it will be deserialized as null without any checks of JsonSetter.

I think it is kind of OK if those checks would be done somewhere later, but it does not seem to be the case (not sure, since not so much familiar with jackson internals)
After all CreatorProperties has been gathered, BeanDeserializer invokes creator.build(...) where PropertValueBuffer.getParameters only check for FAIL_ON_NULL_CREATOR_PROPERTIES

Don't know how to deal with it, yet.
For example, this works (fails as expected), but doesn't look nice:

case class Issue87WorkAroundMapping @JsonCreator(mode = JsonCreator.Mode.DISABLED) (
    id: String, vals: Map[String, String]) {

    @JsonCreator
    private def this(id: String) = this(id, Map.empty)
}

val nullMap: String = """{ "id":"MapID", "vals": null }"""

val mapper = new ObjectMapper with ScalaObjectMapper {
  registerModule(DefaultScalaModule)
  setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.FAIL))
}
val mapping = mapper.readValue[Issue87WorkAroundMapping](nullMap)

@toefel18
Copy link

I've also encountered this problem. I find it not scala like, if you have options, then nulls should be forbidden on deserialization.

@grv87
Copy link

grv87 commented May 28, 2019

I agree with @toefel18. The bug is not in scala module, but in databind.

@grv87
Copy link

grv87 commented May 28, 2019

Most probably FasterXML/jackson-databind#2024

@pjfanning
Copy link
Member

closed due to FasterXML/jackson-databind#2024 - reopen if you think the issue is still there

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

5 participants