当前位置: 首页 > 面试题库 >

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

苏翰学
2023-03-14
问题内容

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

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明确声明您不能在Collections上使用@JsonBackReference。我的问题是,我应该如何解决这个问题?我现在要做的是在父端删除@JsonManagedReference批注,并在子端添加@JsonIgnore。谁能告诉我这种方法的副作用是什么?还有其他建议吗?


问题答案:

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

关系的一端被视为父母。它不需要任何与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实体的一组有限属性。因为省略了“标签”属性,所以不会发生循环引用。

可以在这里找到有关此主题的很好的阅读。它说明了遇到类似情况时的所有可能性。



 类似资料:
  • 我在我的实体中有一种双向的多对多关系。请参见下面的示例: 当我尝试将其序列化为JSON时,我得到了以下异常:' “java.lang.IllegalArgumentException:无法处理托管/反向引用'COLLABORATION_TAG':反向引用类型(java.util.Set)与托管类型(foo.COLLABORATION)不兼容。”。 实际上,我知道这是有道理的,因为javadoc明确

  • 我在和之间具有双向多对多关系。在的帮助下创建两个实体,甚至创建它们的子实体都是简单明了的。 和都可以在的帮助下轻松地自动持久化,如下所示: 然而...更新会导致异常: 我尝试修改的以包括、和/或,但未成功。我们怎么绕过这件事?

  • 我在使用JPA/Hibernate的Spring Boot中有一个多对多实体关系和一些额外属性以及一个复合键,但是实体/实体的JSON序列化会导致循环JSON,这会引发一个异常。 基本表结构如下(cols=实体/表,行=属性): 在Spring Boot中,这表示为以下关系: 其中,两个单独的实体表示为: 每当通过存储库的方法通过API获取s列表时,返回的JSON将无限期地在上递归,导致异常。实体

  • 我有两个类:< code>User和< code>UserProfile。 用户类别: 用户配置文件类: 当我使用此代码时,我在具有多对多关系的表用户配置文件中获得重复的实体。我使用 函数来保存对象。我做错了什么? 然后我删除 cascadeType,出现错误:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。 Hibernate日志:

  • 假设我们有两个实体,Entity和Entity。有多个s。节点可以属于多个集群。因此,在

  • 给定以下具有双向一对多关系的JPA实体 如果我从已经包含一些项目的数据库加载购物车 我想用一个新的物品集合替换购物车中的物品 执行此更换的最简单/最佳方法是什么?理想情况下,我希望生成的SQL语句合理高效,但我的主要目标是使用简洁易读的代码执行替换。 为了明确我所说的替换是什么意思,如果购物车最初包含ID为2、3、4的项目,并且包含4、5、6,那么在替换之后,购物车应该包含ID为4、5、6的项目。