【问题标题】:Cyclic references in a bidirectional many to many relationship双向多对多关系中的循环引用
【发布时间】:2012-11-17 18:44:57
【问题描述】:

我的实体中存在双向多对多关系。请看下面的例子:

public class Collaboration {

    @JsonManagedReference("COLLABORATION_TAG")
    private Set<Tag> tags;

}

public class Tag {

    @JsonBackReference("COLLABORATION_TAG")
    private Set<Collaboration> collaborations;

}

当我尝试将其序列化为 JSON 时,出现以下异常:`

"java.lang.IllegalArgumentException: 无法处理托管/返回 参考'COLLABORATION_TAG':反向参考类型(java.util.Set)不是 兼容托管类型(foo.Collaboration)。

实际上,我知道这是有道理的,因为 javadoc 明确指出您不能在集合上使用 @JsonBackReference。我的问题是,我应该如何解决这个问题?我现在所做的是删除父端的@JsonManagedReference 注释,并在子端添加@JsonIgnore。有人能告诉我这种方法的副作用是什么吗?还有其他建议吗?

【问题讨论】:

标签: java json many-to-many jackson


【解决方案1】:

我最终实现了以下解决方案。

关系的一端被认为是父级。它不需要任何与 Jackson 相关的注释。

public class Collaboration {

    private Set<Tag> tags;

}

另一边的关系实现如下。

public class Tag {

    @JsonSerialize(using = SimpleCollaborationSerializer.class)
    private Set<Collaboration> collaborations;

}

我正在使用自定义序列化程序来确保不会发生循环引用。序列化器可以这样实现:

public class SimpleCollaborationSerializer extends JsonSerializer<Set<Collaboration>> {

    @Override
    public void serialize(final Set<Collaboration> collaborations, final JsonGenerator generator,
        final SerializerProvider provider) throws IOException, JsonProcessingException {
        final Set<SimpleCollaboration> simpleCollaborations = Sets.newHashSet();
        for (final Collaboration collaboration : collaborations) {
            simpleCollaborations.add(new SimpleCollaboration(collaboration.getId(), collaboration.getName()));                
        }
        generator.writeObject(simpleCollaborations);
    }

    static class SimpleCollaboration {

        private Long id;

        private String name;

        // constructors, getters/setters

    }

}

此序列化程序将仅显示 Collaboration 实体的有限属性集。因为省略了“tags”属性,所以不会出现循环引用。

可以在here 找到有关此主题的好读物。它解释了当您遇到类似情况时的所有可能性。

【讨论】:

【解决方案2】:

jackson 2 库中提供了非常方便的接口实现

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Collaboration { ....

在 Maven 中

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.0.2</version>
</dependency>

【讨论】:

  • 仅供参考:我认为正确的 maven 依赖项应该是 &lt;artifactId&gt;jackson-annotations&lt;/artifactId&gt;。无论如何,这对我的构建有用。
猜你喜欢
  • 1970-01-01
  • 2017-11-11
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
相关资源
最近更新 更多