question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JsonGenerationException: expected field name while writing ObjectId reference

See original GitHub issue

Issue submission requested by Tatu from jackson-user list question: https://groups.google.com/forum/#!topic/jackson-user/GOj0uGn_nTg

I’m using Jackson 2.8.0 to serialize some JPA Entities over a REST API with Spring Data REST. I’m having a problem with serializing an Array of Entities that contain references to the same child object. All objects are using JsonIdentityInfo as below, where the key property is a Long @Id field.

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "key", scope = MyClass.class)

I believe the expected JSON should look like the below. The relevant object is supportEmailAddress.

"companies" : [ {
  "key" : 1,
  "name" : "company1",
  "supportEmailAddress" : {
    "key" : 1,
    "emailAddress" : "email@support.com"
  }
  "owner" : {
    "key" : 1,
    "name" : "owner 1",
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/1"
      }
    }
  }
}, {
  "key" : 2,
  "name" : "company2",
  "supportEmailAddress" : {[1]}
  "owner" : {
    "key" : 2,
    "name" : "owner 2",
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/2"
      }
    }
  }

The first time the child object is referenced, it serializes correctly. The second time, it fails with the stack trace below.

Caused by: com.fasterxml.jackson.core.JsonGenerationException: Can not write a number, expecting field name
at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1676)
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._verifyValueWrite(UTF8JsonGenerator.java:925)
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeNumber(UTF8JsonGenerator.java:787)
at com.fasterxml.jackson.databind.ser.std.NumberSerializers$LongSerializer.serialize(NumberSerializers.java:188)
at com.fasterxml.jackson.databind.ser.impl.WritableObjectId.writeAsId(WritableObjectId.java:35)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:584)
at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanSerializer.serialize(UnwrappingBeanSerializer.java:114)
at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:127)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:985)
at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:193)
at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:140)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:985)
at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$NestedEntitySerializer.serialize(PersistentEntityJackson2Module.java:356)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)x
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:600)
at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanSerializer.serialize(UnwrappingBeanSerializer.java:114)
at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:127)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:985)
at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:193)
at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:140)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:616)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:519)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:31)
at org.springframework.hateoas.hal.Jackson2HalModule$HalResourcesSerializer.serialize(Jackson2HalModule.java:340)
at org.springframework.hateoas.hal.Jackson2HalModule$HalResourcesSerializer.serialize(Jackson2HalModule.java:302)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1428)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:930)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:269)
... 57 more

If I remove the JsonIdentityInfo, I get the results back correctly. However, there are no Object references, and the full child object is serialized every time it is referenced. I’m concerned that this “fix” is not effective, because I originally added the JsonIdentityInfo annotations to get around some recursive relationships (ORM bi-directional stuff). If I have to remove them every time I might refer to the same instance in a result set, what is the point of the JsonIdentityInfo annotation in the first place?

I’m sure I’m just applying something incorrectly, but I’m not able to find documentation on what I may be missing. Do I need a custom serializer to make use of this feature?

Attaching minimal example project. Extract and execute gradlew bootRun. Navigate to localhost:8080/company to see the bug. Full Stack trace is not logged by default and would require debugging or custom exception handler to be applied. Error message is visible on console. Navigating to individual objects (e.g. /company/1) works correctly.

To validate /company works without the duplicate child object, edit rest-api/src/main/resources/data.sql and either set SUPPORT_EMAIL_ADDRESS null or to 3 for company 1 or company 3 and restart the application.

Ex: 2016-07-14T13:50:49,734 WARN [mvc.support.DefaultHandlerExceptionResolver] [http-nio-8080-exec-2] Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Can not write a number, expecting field name; nested exception is com.fasterxml.jackson.core.JsonGenerationException: Can not write a number, expecting field name

databind-bug.zip

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:2
  • Comments:31 (23 by maintainers)

github_iconTop GitHub Comments

2reactions
cowtowncodercommented, Jul 17, 2018

In case anyone asks: no progress, no idea what to do here, no fix.

0reactions
cowtowncodercommented, Apr 2, 2020

Not sure what could be done here; closing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JsonGenerationException when serializing nested object ...
I tried to write a deserializer and is not working when used in a map. can you give some input here.. stackoverflow.com/questions/54028149/… – ......
Read more >
System.JSONException: Can not write a field name, expecting ...
You are writting a field name without starting the object. Try adding a writeStartObject() just after creting the generator. Something like:
Read more >
JsonIdentityInfo and serializing ObjectId references - expected ...
JsonGenerationException : Can not write a number, expecting field name. at com.fasterxml.jackson.core.JsonGenerator.
Read more >
WriterBasedJsonGenerator (Jackson-core 2.7.0 API)
Method for outputting given value as JSON number. Can be called in any context where a value is expected (Array value, Object field...
Read more >
Class WriterBasedJsonGenerator - Adobe Support
Field names can only be written in Object context (check out JSON specification for details), when field name is expected (field names alternate...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found