【问题标题】:Handling recursive reference with collections (many to many) on Json Resteasy在 Json Resteasy 上使用集合(多对多)处理递归引用
【发布时间】:2015-04-19 15:28:02
【问题描述】:

我遇到了一个我无法解决的问题。 我有 2 个 DTO,一个具有另一个 DTO 的集合属性。

public class UnidadAsistencialDTO 

private Long id;
private String descripcion;
@JsonManagedReference
private Collection<ServicioDTO> servicios;


public class ServicioDTO 

private Long id;
private String nombre;
private Collection<EspecialidadMinDTO> especialidades;
@JsonBackReference
private Collection<UnidadAsistencialDTO> unidadesAsistenciales;

所以当我尝试获取这些对象时,我遇到了这个异常

11:52:46,708 WARN [org.jboss.resteasy.core.SynchronousDispatcher] (http-localhost/127.0.0.1:8080-1) 执行 POST /agenda: org.jboss.resteasy.spi.ReaderException: org 失败.codehaus.jackson.map.JsonMappingException:无法处理托管/反向引用'defaultReference':反向引用类型(java.util.Collection)与托管类型(ar.org.inssjp.asthenis.dto.agenda.UnidadAsistencialDTO)不兼容 在 org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:202) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:136) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:159) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:216) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19] 在 org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19] 在 org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.4.8.Final-redhat-4.jar:7.4.8.Final-redhat-4] 在 java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_71] 原因:org.codehaus.jackson.map.JsonMappingException:无法处理托管/反向引用'defaultReference':反向引用类型(java.util.Collection)与托管类型(ar.org.inssjp.asthenis.dto.议程.UnidadAsistencialDTO) 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:315) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:620) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:379) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:407) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:352) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findTypedValueDeserializer(StdDeserializerProvider.java:180) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:2829) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2699) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419) 在 org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:106) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:63) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:109) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] 在 org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:169) [resteasy-jaxrs-2.3.8.Final-redhat-3.jar:] ... 27 更多 引起:java.lang.IllegalArgumentException:无法处理托管/反向引用'defaultReference':反向引用类型(java.util.Collection)与托管类型(ar.org.inssjp.asthenis.dto.agenda.UnidadAsistencialDTO)不兼容 在 org.codehaus.jackson.map.deser.BeanDeserializer._resolveManagedReferenceProperty(BeanDeserializer.java:497) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:382) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:407) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:352) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:620) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:379) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:407) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:352) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:620) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:379) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:407) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:352) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:290) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:159) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:283) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:389) [jackson-mapper-asl.jar:1.9.13] 在 org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:310) [jackson-mapper-asl.jar:1.9.13] ... 44 更多

我在一些博客中读到,这些注释“@JsonManagedReference”和“@JsonBackReference”并不能解决双方都有集合时的问题(例如多对多关系)。

你能帮帮我吗?

谢谢

【问题讨论】:

    标签: java json recursion jackson resteasy


    【解决方案1】:

    尝试将此注释添加到类中:

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = UnidadAsistencialDTO.class))
    

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = ServicioDTO.class))
    

    还可以查看this 以供进一步参考。

    编辑

    如果这不起作用(如您的情况),请尝试以下方法:

    @JsonIgnore
    

    这方面的文档是here

    更新

    如果你需要一个父母和他们的孩子列表孩子参考父母,我建议你采取以下任何一种方式:

    1. 调用父级时删除子级中父级的引用,调用子级时删除子级的引用(仅在内存中和将 DTO 转换为 json 之前)。你最终会得到这样的结果:

      { “名称”:“父母”, “孩子们”:[ { “名称”:“孩子1”, “父”:空 },{ “名称”:“孩子2”, “父”:空 } ] }

      没有null 来自子级对父级的引用。另外,作为提示,请确保不要删除父引用INSIDE事务上下文。

    2. 如果在您的子项(或父项,取决于您查询的内容)内部有一个 null 引用不正确,您可以创建一组新的 DTO 映射到该结构您正在寻找。 如果您这样做,请查看this 以了解正确的方法。

    【讨论】:

    • 还有一个问题,你提到的那些注释我在哪里可以找到它们?我的意思是,我应该在我的 POM 文件中添加哪个库?我正在使用 Jboss EAP。
    • Here's API 的链接,here's maven 依赖的链接
    • 我添加了你告诉我的注释,现在我有另一个例外。
    • 18:35:01,596 WARN [org.jboss.modules] (http-localhost/127.0.0.1:8080-4) 无法定义类 org.codehaus.jackson.map.JsonMappingException$Reference来自本地模块加载器 515c9cc0 的模块“org.codehaus.jackson.jackson-mapper-asl:main”(查找器:本地模块查找器 17372afb(根:C:\Users\\workspace\jboss-eap-6.3\modules,C:\用户\\workspace\jboss-eap-6.3\modules\system\layers\base)): java.lang.StackOverflowError at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    • 那是我唯一知道的把戏。但是,如果您分享新错误,我们可以继续找出问题所在
    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 2020-03-30
    • 2019-07-28
    • 2016-10-09
    • 1970-01-01
    • 2011-12-30
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多