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

Class with @JsonTypeInfo cannot be @JsonUnwrapped #81

Closed
pschanely opened this issue Sep 27, 2012 · 10 comments
Closed

Class with @JsonTypeInfo cannot be @JsonUnwrapped #81

pschanely opened this issue Sep 27, 2012 · 10 comments
Milestone

Comments

@pschanely
Copy link

... in version 2.0.6. It yields an internal error "Can not start object, expecting field name".

package scratch;

import static org.junit.Assert.*;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ScratchTest {

  @JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="_obj_cls")
  public class SubObject {}

  public class MainObject {
    @JsonUnwrapped
    public SubObject subObject;
  }

  @Test
  public void test() throws Exception {
    MainObject item = new MainObject();
    item.subObject = new SubObject();
    ObjectMapper mapper = new ObjectMapper();
    String encoded = mapper.writer().writeValueAsString(item);
  }

}
com.fasterxml.jackson.core.JsonGenerationException: Can not start an object, expecting field name
    at com.fasterxml.jackson.core.base.GeneratorBase._reportError(GeneratorBase.java:412)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._verifyValueWrite(WriterBasedJsonGenerator.java:824)
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeStartObject(WriterBasedJsonGenerator.java:261)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeSerializer.writeTypePrefixForObject(AsPropertyTypeSerializer.java:48)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeWithType(BeanSerializerBase.java:437)
    at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:102)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:525)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:143)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:108)
    at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:570)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:494)
    at scratch.ScratchTest.test(ScratchTest.java:26)

Appears to me it's because UnwrappingBeanSerializer is not overriding serializeWithType(). The fix doesn't look simple, though, as the TypeSerializer interface seems to assume an embedded object.

@cowtowncoder
Copy link
Member

Yes, this would be tricky to support properly, and requires both serialization and deserialization to work around the complications. There is a chance that this combination can not be supported; but if so, it could either throw a more descriptive exception, or just ignore unwrapping handling. Both approaches have their downsides.

Not sure what Afterburner does, although I would guess that it might just disable unwrapping handling altogether?

@pschanely
Copy link
Author

Yeah, I was incorrect before; afterburner is simply ignoring the @JsonUnwrapped annotation. I would have assumed that an error would be the most appropriate response, personally.

@cowtowncoder
Copy link
Member

Afterburner code is bit fragile since it relies on inheritance, and as unwrapped struct handling is newer than AB, it has not been updated to try to figure out unwrapping aspects if any. But it would probably make sense for AB to avoid optimizing Bean(De)Serializers that do unwrapping and leave it to default handling.
I'll add an RFE for afterburner project.

pgelinas pushed a commit to pgelinas/jackson-databind that referenced this issue Jan 28, 2014
@aleksz
Copy link

aleksz commented Apr 28, 2014

What is the recommended workaround?

@UnquietCode
Copy link
Contributor

I have managed to patch this locally by simply skipping the writing of type id information for properties being unwrapped. Hopefully this is a valid solution? It prevents the error from happening but obviously we still lose the type information. I think that's an ok start, as it at least enables the classes to be used in a top level and unwrapped scenario without error.

@cowtowncoder
Copy link
Member

I added notes on #455; basically I am bit worried about default behavior of skipping writing of type info. But I agree in that failing when trying to write is also not much of a solution... so perhaps a SerializationFeature would be a reasonable starting point.

@UnquietCode
Copy link
Contributor

@cowtowncoder Would the feature basically give Jackson permission to omit type information for these cases?

@cowtowncoder
Copy link
Member

@UnquietCode Right, it would do that. So just guard this feature to be used only when explicitly enabled -- I am still worried about side effects, or this hiding some other problems. It is easier to explain alternative processing when it is explicitly enabled.

@UnquietCode
Copy link
Contributor

Sounds good to me. I added some stubs to #455 for such a feature. Probably some cleanup or renaming is required. I wasn't able to get the full JSON path information into the exception message.

@cowtowncoder cowtowncoder added this to the 2.4.0 milestone May 16, 2014
@cowtowncoder
Copy link
Member

Merged #455, so this is sort of supported now.

cowtowncoder added a commit that referenced this issue May 16, 2014
christophercurrie pushed a commit to christophercurrie/jackson-databind that referenced this issue Jul 19, 2015
Test and bug fix for Issue FasterXML#81: CharTypers.appendQuoted misencodes first 32 Unicode values as '\0000'.
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

4 participants