java 双向多对多关系中的循环引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13630096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:26:19  来源:igfitidea点击:

Cyclic references in a bidirectional many to many relationship

javajsonmany-to-manyHymanson

提问by tstorms

I'm having a bidirectional many to many relationship in my entities. See the example below:

我的实体中有双向多对多关系。请参阅以下示例:

public class Collaboration {

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

}

public class Tag {

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

}

When I try to serialize this to JSON, I'm getting the following exception: `

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

"java.lang.IllegalArgumentException: Can not handle managed/back reference 'COLLABORATION_TAG': back reference type (java.util.Set) not compatible with managed type (foo.Collaboration).

“java.lang.IllegalArgumentException:无法处理托管/返回引用'COLLABORATION_TAG':返回引用类型(java.util.Set)与托管类型(foo.Collaboration)不兼容。

Actually, I know this makes sense because the javadoc explicitly states that you can't use @JsonBackReference on Collections. My question is, how should I address this problem? What I've done for now is remove the @JsonManagedReference annotation on the parent side, and added the @JsonIgnore on the child side. Could someone tell me what the side effects are of this approach? Are there any other suggestions?

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

采纳答案by tstorms

I ended up implementing the following solution.

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

One end of the relationship is considered to be the parent. It does not need any Hymanson related annotation.

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

public class Collaboration {

    private Set<Tag> tags;

}

The other side of the relationship is implemented as follows.

关系的另一面实现如下。

public class Tag {

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

}

I'm using a custom serializer to will make sure that no cyclic references will occur. The serializer could be implemented like this:

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

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

    }

}

This serializer will only show a limited set of the properties of the Collaboration entity. Because the "tags" property is omited, no cyclic references will occur.

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

A good read about this topic can be found here. It explains all possibilities when you're having a similar scenario.

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

回答by Oleksii Kyslytsyn

very handy interface implementation is provided in Hymanson 2 library as

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

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

in maven

在行家

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