-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Part of databind#3072: Make @JacksonInject not fail when there's no corresponding value #5131
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
Part of databind#3072: Make @JacksonInject not fail when there's no corresponding value #5131
Conversation
…NOWN_INJECT_VALUE to determine whether to throw an exception when JacksonInject properties are not found
First of all: thank you for contributing this! Added a note on CLA in the other PR -- only needs to be done once to cover both. |
gonna provide the CLA asap |
CLA just sent |
if (_injectableValues == null) { | ||
return reportBadDefinition(ClassUtil.classOf(valueId), String.format( | ||
"No 'injectableValues' configured, cannot inject value with id [%s]", valueId)); | ||
final JacksonInject.Value injectableValue = getAnnotationIntrospector() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we would not be doing annotation introspection during actual deserialization; pretty much everything is and should be introspected during deserializer construction.
Need to figure out how to avoid that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. I opened this PR on my fork to let you evaluate the idea before pushing here a quite different approach.
Basically, I added the _optional
field in the ValueInjector so that the BeanDeserializerFactory constructs them with it.
Tests are passing. If it's ok, i'll do the usual overload-and-deprecate before merging it on this one and continue the review.
Additionally: should I try to move the FAIL_ON_UNKNOWN_INJECT_VALUE
feature in some other early phase, or it's fine to evaluate it in DeserializationContext
and InjectableValues
? We cannot do that in the same place (BeanDeserializerFactory
) since it's called too early:
ObjectReader reader = newReader() // the BeanDeserializerFactory kicks in here, before de-activating the feature
.without(FAIL_ON_UNKNOWN_INJECT_VALUE);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to look deeper to have an informed opinion, but by default I assume you know what you are doing (seems that way), i.e. your intuition is probably right. And yes, DeserializationFeature
s can be change on per-call basis (so decision based on them need to be more dynamic), whereas annotations are static (even mix-ins) and decision likewise more dynamic. In this case we then we have "interesting" combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@giulong Ok yes, checking DeserializationFeature.FAIL_ON_UNKNOWN_INJECT_VALUE
is cheap and can/should be done as needed, not earlier. Only annotation access need to be front-loaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And yes, I think the approach in referenced PR makes sense -- let's go with that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
Outdated
Show resolved
Hide resolved
Object ob = _values.get(key); | ||
if (ob == null && !_values.containsKey(key)) { | ||
throw new IllegalArgumentException("No injectable id with value '"+key+"' found (for property '"+forProperty.getName()+"')"); | ||
final JacksonInject.Value injectableValue = ctxt.getAnnotationIntrospector() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here too; really should handle introspection so we would not need to do that processing every time injectable value not found. Not sure if that is doable.
Received, we are good to go wrt that. |
…uring deserializer construction
…ect-spike feat(FasterXML#3072): moving JacksonInject annotation introspection during des…
{ | ||
_member.setValue(beanInstance, findValue(context, beanInstance)); | ||
final Object value = findValue(context, beanInstance); | ||
if (!JacksonInject.Value.empty().equals(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure why this test is needed... ?
@@ -0,0 +1,124 @@ | |||
package com.fasterxml.jackson.databind.tofix; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong package: this is for failing tests :)
(I will move to under .../deser/inject
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Filed #5151 for some follow-up work.
As requested in #3072, deserialization will not fail if the injectable values provided to the object reader does not contain a property and:
that property is explicitly annotated with
@JacksonInject(optional = OptBoolean.TRUE)
orthe
DeserializationFeature.FAIL_ON_UNKNOWN_INJECT_VALUE
is switched off, i.e.: