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

Injection when there is cyclic references fails #538

Closed
WaDelma opened this issue Sep 9, 2014 · 7 comments
Closed

Injection when there is cyclic references fails #538

WaDelma opened this issue Sep 9, 2014 · 7 comments
Milestone

Comments

@WaDelma
Copy link

WaDelma commented Sep 9, 2014

When trying to debug problem in my project I was able reduce the problem to this simple case...
It seems that Jackson cannot handle injecting values via constructor when there is cyclic references.
The error disappears when I remove the cyclic reference or inject from either constructor.

com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Could not resolve Object Id [1] (for [simple type, class test.Test$A]).
 at [Source: {"@id":1,"b":{"@id":2,"a":1}}; line: 1, column: 28]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectId(BeanDeserializerBase.java:1042)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1076)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:137)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:126)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:373)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1056)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:264)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1028)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:122)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:373)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1056)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:264)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1028)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:122)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1269)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:896)
    at test.Test.main(Test.java:23)
package test;

import java.io.IOException;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Test {
    public static void main(String[] args) {
        A a = new A(null);
        B b = new B(null);
        a.b = b;
        b.a = a;
        try {
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(a);
            InjectableValues.Std inject = new InjectableValues.Std();
            inject.addValue("i1", "e1");
            inject.addValue("i2", "e2");
            mapper.reader(inject).withType(A.class).readValue(json);
            System.out.println(json);
        } catch (IOException expection) {
            expection.printStackTrace();
        }
    }

    @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
    public static class A {
        public B b;
        public A(@JacksonInject("i1") String injected) {}
    }

    @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
    public static class B {
        public A a;
        public B(@JacksonInject("i2") String injected) {}
    }
}
@cowtowncoder
Copy link
Member

Ok thanks. Creator arguments are known to be bit more problematic, in combination with object and/or type ids. But I hope this can be resolved.

cowtowncoder added a commit that referenced this issue Oct 17, 2014
@cowtowncoder
Copy link
Member

Added unit test under failing: problem reproduced as described.

@cowtowncoder
Copy link
Member

The underlying reason has to do with Object Id being found ok and all, but due to use of creator methods, binding from id to instance can not proceed until the whole object is complete.
That should be fine with the new forward-reference handling, but for some reason this particular code path does not catch intermediate exception; method that throws it is in

SettableBeanProperty.deserialize(JsonParser jp, DeserializationContext ctxt) // about line 528

which is not overridden by ObjectIdReferenceProperty, unlike most other methods. And given that method is final, it'd be good to avoid having to override it since it is in critical path (from performance perspective).

@cowtowncoder
Copy link
Member

Hmmh. Actually, overriding that method would not help either, as it can not produce the object.
Rather, somehow within there, a missing reference should be set, to be resolved at a later point.

@pgelinas This may be something you'll have better luck solving eventually.

@cowwoc
Copy link

cowwoc commented Dec 1, 2014

I think #639 might be a duplicate of this issue.

Can someone please confirm? (Feel free to grab the testcase from that issue if needed)

@cowtowncoder cowtowncoder modified the milestones: 2.2, 2.8.0 Jun 15, 2016
@cowtowncoder
Copy link
Member

Seems to be resolved for 2.8.0, possibly related to fixes to forwards-refs handling.

@cowtowncoder
Copy link
Member

Note: Failing for Jackson 3.0.0-SNAPSHOT (master).

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

3 participants