Skip to content

Default Values for Optionals Or Reject All Nulls #988

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
NTCoding opened this issue Oct 28, 2015 · 6 comments
Closed

Default Values for Optionals Or Reject All Nulls #988

NTCoding opened this issue Oct 28, 2015 · 6 comments

Comments

@NTCoding
Copy link

Hello,

I think your library is great but it doesn't quite work for one Scala use case. When there is a property of type Option I want it to set a default value of none even when FAIL_ON_MISSING_CREATOR properties is true.

I would like to do this conventionally without having to apply any annotations to the code. Could you give me advice on the best way to implement this and I will do the work and send a pull request.

Something in here seems sensible:

 protected Object _findMissing(SettableBeanProperty prop) throws JsonMappingException
    {
        // First: do we have injectable value?
        Object injectableValueId = prop.getInjectableValueId();
        if (injectableValueId != null) {
            return _context.findInjectableValue(prop.getInjectableValueId(),
                    prop, null);
        }
        // Second: required?
        if (prop.isRequired()) {
            throw _context.mappingException("Missing required creator property '%s' (index %d)",
                    prop.getName(), prop.getCreatorIndex());
        }
        if (_context.isEnabled(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES)) {
            throw _context.mappingException("Missing creator property '%s' (index %d); DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES enabled",
                    prop.getName(), prop.getCreatorIndex());
        }
        // Third: default value
        JsonDeserializer<Object> deser = prop.getValueDeserializer();
        return deser.getNullValue(_context);
    }

Perhaps a new service "defaultCreatorValueProvider" or similar?

If there is a better way, or even an existing way, please let me know.

Thanks

@cowtowncoder
Copy link
Member

Definition of FAIL_ON_MISSING_CREATOR is pretty clear -- fail if value is missing from incoming JSON. I don't see why its semantics should be changed.

But the other case of allowing missing properties should handle default value for Option value correctly; similar to how primitive values are handled (they can not be set to null). As long as deserializer used for Option defines non-null return value for getEmptyValue(...), which is called to get value to pass to creator method.

@NTCoding
Copy link
Author

Hi,

I understand that you are a Java developer and perhaps are not familiar with monads and optionals (apologies if that is condescending). However, an Option[T] is explicitly stating that the type is optional - part of the type's DNA is that there may be no value for it - and hence a missing constructor value means it should default to a value of None.

It is explained in more detail here: FasterXML/jackson-module-scala#203

If an object has two properties - one is optional and one is not - the type system is expressing what is mandatory - the optional values. Is there any way to do this currently - if the value is missing throw an exception unless it is an Option?

In the "other case" you mention, then it would not fail if a value was missing from a non-optional type and the value would default to null. Would you consider a pull request with a new deserialization option: "REJECT_ALL_NULL_VALUES" or are you completely against adding new functionality that helps to support Scala optionals?

@NTCoding
Copy link
Author

I've added a pull request to demonstrate another possible way of solving this problem without interfering with the fail on creator properties. Please let me know what you think: #990

I'm happy to put in more effort if you give me guidance.

Thanks

@NTCoding NTCoding changed the title Default Values for Optionals Default Values for Optionals Or Reject All Nulls Oct 29, 2015
@cowtowncoder
Copy link
Member

@NTCoding keep in mind Jackson knows nothing about Scala, and generally does not care.
That Scala has additional semantics does not really matter -- null is a null, and Optional is NOT null. There's no two ways about that. Instead Optional's (and other referential types, ReferentialType as of 2.6) do have concept of "absent", and that is separated.

I hope to have a look at the proposal in near future, but I am bit backlogged due to major rewrite of type handling to resolve long-standing problems with generic type resolution (wrt type aliasing, mostly).

@NTCoding
Copy link
Author

NTCoding commented Nov 5, 2015

Thanks for the feedback. I guess the code is open source so I can publish my own fork for now.

@cowtowncoder
Copy link
Member

Replaced with #1402, which I think would provide all the pieces needed. Scala module might need something additional (and definitely needs to support this); but from jackson-databind perspective I think this should be sufficient. Planning to get implemented for 2.9.

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