-
Notifications
You must be signed in to change notification settings - Fork 79
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
How to bypass MrBean for types with existing deserialization logic #99
Comments
Hmmh. Interesting question. One concern I have is that of As to whether it could/should be part of standard Mr Bean, that is a good question. If there's enough test coverage for some scenarios (addition of custom (de)serializer(s), it seems like potentially useful addition. But I am open to something like this being added as a standard feature; it could go in 2.12.0 (api additions need to go in new minor versions). |
The method in question is called by Additional ContextWhat I'm seeing is that MrBean is materializing interfaces/abstract classes that contain Therefore the scope of this issue is confined to:
Refining the WorkaroundAfter looking into this further, I think the If the above paragraph holds, then I think we can "simplify" the workaround to:
Problems generalizing the solutionIn testing this logic further (against 2.10 fwiw), I've observed that If the type containing What's more, the decision made by In general, I'm not sure how best to proceed on a patch for this issue, because I have the following questions:
In general, it seems like these questions/limitations prevent MrBean from safely determining for a particular type whether Jackson databinding is already configured to handle the specified type, so I'm starting to think that this issue may be better addressed in the databinding project. Hopefully, my analysis here is reasonably coherent. Let me know if anything is unclear, and of course, let me know what you think about these concerns. |
@robbytx One quick note: yes, "type handler" only gets assigned when As I mentioned earlier, handlers that are (in some cases) attached to I also suspect that some more support may be needed from Some challenges here are:
While I am not sure how to address these, it might be useful to have a setting to at least configure logic for types not to materialize -- perhaps we can start more reliably avoiding specific set of types. Also: adding some failing tests (under |
@cowtowncoder thanks for your response. I'm glad that it seems like I'm not too far off-track. Thanks for clarifying the current challenges and considerations.
Yeah, that's what I was thinking, even if it's not what I was hoping.
This is currently possible, although awkward, by overriding I'd rather try to provide some sort of configuration that would automatically handle certain use cases. Some options I can see:
I'm not very familiar with default typing, so it's a bit hard for me to imagine how these should interact. Clearly the
This matches how I think Jackson should handle So... the more I think about this, the more I'm left with the impression that MrBean is simply getting involved too early in the type resolution process. I'd be interested whether you agree with this, or whether there are use cases that I'm failing to consider, where MrBean should preempt other annotations/default typing. |
Yes, it is possible that the effort would be better spent on I think that Problem really is that (value) deserializer handling is quite isolated from type deserializers (type deserializer is what handles type<->id conversion, inclusion/extraction), especially during construction. |
In further testing, I've discovered a subtle issue where the solution I proposed above may fail. As I noted above, the issue depends on the context in which the type is first encountered and therefore materialized:
The scenario where I'm seeing the failure is if a sub-type (to be materialized by MrBean) is referenced directly (as opposed to indirectly via its parent type) as the property (or the element/key/value type of some property) of another type. In this scenario, it appears that the Here is some example code: package example;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.mrbean.AbstractTypeMaterializer;
import com.fasterxml.jackson.module.mrbean.MrBeanModule;
public class Test {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "id", defaultImpl = SubType.class)
public interface PolymorphicType {
}
public interface SubType extends PolymorphicType {
}
public interface PolymorphicTypeContainer {
PolymorphicType getValue();
}
public interface SubTypeContainer {
SubType getValue();
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper()
.registerModule(new MrBeanModule(new AbstractTypeMaterializer() {
@Override
protected boolean _suitableType(JavaType type) {
return type.getTypeHandler() == null && super._suitableType(type);
}
}));
// This line breaks because type.getTypeHandler() will return an AsPropertyTypeDeserializer due to inherited @JsonTypeInfo
System.out.println(mapper.readValue("{\"value\":{}}", SubTypeContainer.class).getValue());
System.out.println(mapper.readValue("{\"value\":{}}", PolymorphicTypeContainer.class).getValue());
}
} that fails (in Jackson 2.11.3 / 2.12.1) with:
If you switch the order such that I'm noting this primarily to caution anyone who attempts use the workaround that this issue could arise if you have direct references to subtypes. It appears the simplest workaround to this issue is to force early materialization of such types via |
This is more of a question, possibly with a suggested change for greater compatibility.
I'm trying to better understand MrBean's incompatibility with polymorphic types, since I'd really like to use both MrBean and
@JsonTypeInfo
.From my limited testing, it appears that I can override the
_suitableType
method (not sure if that's officially supported), so that I can bypass MrBean's materialization for specific abstract types. When I do this with a polymorphic interface annotated by@JsonTypeInfo
, everything seems to work -- Jackson's polymorphic type resolution kicks in, and MrBean can still be used to materialize the specific subclasses/interfaces as desired.Since I've got that working, I'm exploring how to implement the
_suitableType
method generically, and I've found that the following override seems to do the job:As far as I can tell from my limited testing (and review of Jackson's code in this area),
JavaType.hasHandlers
will return true if the type has a dedicated TypeDeserializer or other deserializer instance. This seems to always be the case for classes that are annotated with@JsonTypeInfo
, as well as any other cases where a specific deserializer has been registered.So, my question is:
I should note that I'm interested exclusively in the deserialization use case, so perhaps I'm overlooking some complexities in the serialization use case.
The text was updated successfully, but these errors were encountered: