Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Spring数据REST-JsonGenerationException:无法写入数字,应为字段名_Spring Boot_Spring Data_Spring Data Rest_Jpa 2.1_Jackson2 - Fatal编程技术网

Spring boot Spring数据REST-JsonGenerationException:无法写入数字,应为字段名

Spring boot Spring数据REST-JsonGenerationException:无法写入数字,应为字段名,spring-boot,spring-data,spring-data-rest,jpa-2.1,jackson2,Spring Boot,Spring Data,Spring Data Rest,Jpa 2.1,Jackson2,我在使用SpringBootStarter的SpringDataREST应用程序中遇到了一个问题。我用各种关系定义了许多实体。我可以通过键(通常)检索它们,但是我在一些相同对象的集合中遇到了问题。我想知道这是一个JsonIdentityInfo问题,还是为了防止循环JSON生成而“破坏”了唯一标识符 公司表中约有500个条目,页面大小默认为20。转到默认端点(/company),它将返回以下错误。我可以调出没有问题的单个公司(/company/1),包括创建JSON异常时它试图生成的同一家公司

我在使用SpringBootStarter的SpringDataREST应用程序中遇到了一个问题。我用各种关系定义了许多实体。我可以通过键(通常)检索它们,但是我在一些相同对象的集合中遇到了问题。我想知道这是一个JsonIdentityInfo问题,还是为了防止循环JSON生成而“破坏”了唯一标识符

公司表中约有500个条目,页面大小默认为20。转到默认端点(/company),它将返回以下错误。我可以调出没有问题的单个公司(/company/1),包括创建JSON异常时它试图生成的同一家公司

当我进入异常堆栈时,我看到它正在尝试为supportEmailAddress字段生成JSON。这是可以被多个公司行引用的行。公司也有在此表中包含电子邮件地址的联系人,但这些电子邮件地址通常不会在公司或联系人之间共享

注意:我已经用类似的堆栈跟踪查看了SO问题,但该问题似乎围绕自定义序列化程序展开。我不是使用自定义序列化程序

我试过几件事:

  • 带和不带scope属性的JsonIdentityInfo
  • JsonManagedReference和JsonBackReference
  • @对@Id字段的访问(AccessType.PROPERTY)
图书馆版本:

ext['hibernate.version'] = '5.1.0.Final'
ext['hibernateVersion'] = '5.1.0.Final'
ext['springVersion'] = '2.5.1.RELEASE'
ext['springBootVersion'] = '1.3.5.RELEASE'
ext['springDataCommonsVersion'] = '1.12.1.RELEASE'
ext['springDataJpaVersion'] = '1.10.1.RELEASE'
ext['springIntegrationVersion'] = '4.2.6.RELEASE'
ext['querydslVersion'] = '4.1.0'
ext['jacksonVersion'] = '2.8.0'
ext['jacksonJsr310Version'] = '2.8.0'
我已尝试通过序列化进行调试,根本问题是序列化程序在处理company.supportEmailAddress.key时会混淆。它正试图输出键值,但序列化程序希望下一个是键名。当第二次引用相同的supportEmailAddress id时,会发生此错误

更新至Jackson 2.8.0。没有变化

我在最后添加了一个简化的手写JSON示例,以显示我所期望的结构。如您所见,这两家公司引用了相同的supportEmailAddress对象(相同的id)。如果我更改为其他id,它将正确呈现。我相信第二个引用实际上只会输出id,而不是对象的其余部分,因为它已经序列化了一次。据我所知,这是一个标准功能,我还没有做过任何与更改Jackson默认功能相关的事情

简化实体(省略访问器):

公司:

@Entity
@Table(name = "T_Company")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "key", scope = Company.class)
public class Company extends AbstractCustomEntity<Long> {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "COMPANY_ID")
private Long key;

@Size(max = 50)
@Column(name = "NAME", nullable = false, length = 50, unique = true)
private String name;

@OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "company")
private Set<Alias> aliases;

@ManyToMany(mappedBy = "company")
private Set<Owner> owner;

@OneToMany(mappedBy = "agency", cascade = CascadeType.ALL)
private Set<Contact> contacts;

@ManyToOne
@JoinColumn(name = "SUPPORT_EMAIL_ADDRESS_ID")
private EmailAddress supportEmailAddress;
JSON示例:

{
  "_embedded" : {
"companies" : [ {
  "key" : 1,
  "name" : "company1",
  "supportEmailAddress" : {
    "key" : 1,
    "emailAddrType" : "support",
    "emailAddress" : "email@support.com"
  }
  "aliases" : [ ],
  "contacts" : [ ],
  "owner" : {
    "key" : 1,
    "name" : "owner 1",
    "contacts" : [ ],
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/1"
      }
    }
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/company/1"
    },
    "company" : {
      "href" : "http://localhost:8080/company/1"
    },
    "aliases" : {
      "href" : "http://localhost:8080/company/1/aliases"
    },
    "contacts" : {
      "href" : "http://localhost:8080/company/1/contacts"
    }
  }
}, {
  "key" : 2,
  "name" : "company2",
  "supportEmailAddress" : {
    "key" : 1,
    "emailAddrType" : "support",
    "emailAddress" : "email@support.com"
  }
  "aliases" : [ ],
  "contacts" : [ ],
  "owner" : {
    "key" : 2,
    "name" : "owner 2",
    "contacts" : [ ],
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/2"
      }
    }
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/company/2"
    },
    "company" : {
      "href" : "http://localhost:8080/company/2"
    },
    "aliases" : {
      "href" : "http://localhost:8080/company/2/aliases"
    },
    "contacts" : {
      "href" : "http://localhost:8080/company/2/contacts"
    }
  }
} ]
  },
  "_links" : {
"self" : {
  "href" : "http://localhost:8080/company"
},
"profile" : {
  "href" : "http://localhost:8080/profile/company"
},
"search" : {
  "href" : "http://localhost:8080/company/search"
}
  },
  "page" : {
"size" : 20,
"totalElements" : 2,
"totalPages" : 1,
"number" : 0
  }
}

我在嵌套实体(例如,
@OneToMany(mappedBy=“owner”,cascade=CascadeType.ALL))上指定了EAGER fetch时遇到了相同的错误
私人设置联系人;
在您的
所有者
实体上)

一旦嵌套集合中有1个以上的项,序列化就停止工作。我可以通过在嵌套集合上指定
FetchType.LAZY
来解决这个问题,我想这样序列化程序就不会与递归混淆了吧

我想听听更熟悉杰克逊的人的合理解释

@Entity
@Table(name = "T_EMAIL_ADDR")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "key", scope = EmailAddress.class)
public class EmailAddress extends AbstractCustomEntity<Long> {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "EMAIL_ADDRESS_ID")
private Long key;

@Column(name = "EMAIL_ADDRESS_TYPE_NME")
@Enumerated(EnumType.STRING)
private EmailAddrType emailAddrType;

@Size(max = 200)
@Email
@Column(name = "EMAIL_ADDR", length = 200, nullable = false, updatable = false)
private String emailAddress;
@Entity
@Table(name = "T_CONTACT")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "CATG", length = 6)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "key", scope = Contact.class)
public abstract class Contact extends AbstractCustomEntity<Long> {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "CONTACT_ID")
private Long key;

@Column(name = "CONTACT_NME", length = 100)
@Size(max = 100)
private String name;

@OneToOne
@JoinColumn(name = "EMAIL_ADDRESS_ID")
private EmailAddress emailAddress;
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
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:276)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222)
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
at org.springframework.data.rest.webmvc.ResourceProcessorHandlerMethodReturnValueHandler.handleReturnValue(ResourceProcessorHandlerMethodReturnValueHandler.java:113)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:220)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
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)
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
{
  "_embedded" : {
"companies" : [ {
  "key" : 1,
  "name" : "company1",
  "supportEmailAddress" : {
    "key" : 1,
    "emailAddrType" : "support",
    "emailAddress" : "email@support.com"
  }
  "aliases" : [ ],
  "contacts" : [ ],
  "owner" : {
    "key" : 1,
    "name" : "owner 1",
    "contacts" : [ ],
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/1"
      }
    }
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/company/1"
    },
    "company" : {
      "href" : "http://localhost:8080/company/1"
    },
    "aliases" : {
      "href" : "http://localhost:8080/company/1/aliases"
    },
    "contacts" : {
      "href" : "http://localhost:8080/company/1/contacts"
    }
  }
}, {
  "key" : 2,
  "name" : "company2",
  "supportEmailAddress" : {
    "key" : 1,
    "emailAddrType" : "support",
    "emailAddress" : "email@support.com"
  }
  "aliases" : [ ],
  "contacts" : [ ],
  "owner" : {
    "key" : 2,
    "name" : "owner 2",
    "contacts" : [ ],
    "_links" : {
      "company" : {
        "href" : "http://localhost:8080/company/2"
      }
    }
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/company/2"
    },
    "company" : {
      "href" : "http://localhost:8080/company/2"
    },
    "aliases" : {
      "href" : "http://localhost:8080/company/2/aliases"
    },
    "contacts" : {
      "href" : "http://localhost:8080/company/2/contacts"
    }
  }
} ]
  },
  "_links" : {
"self" : {
  "href" : "http://localhost:8080/company"
},
"profile" : {
  "href" : "http://localhost:8080/profile/company"
},
"search" : {
  "href" : "http://localhost:8080/company/search"
}
  },
  "page" : {
"size" : 20,
"totalElements" : 2,
"totalPages" : 1,
"number" : 0
  }
}