当前位置: 首页 > 知识库问答 >
问题:

使用复合键循环JSONHibernate多对多关系

祁博雅
2023-03-14

我在使用JPA/Hibernate的Spring Boot中有一个多对多实体关系和一些额外属性以及一个复合键,但是实体/实体的JSON序列化会导致循环JSON,这会引发一个异常。

基本表结构如下(cols=实体/表,行=属性):

在Spring Boot中,这表示为以下关系:

@Embeddable
class UserRoleKey implements Serializable {

  @Column(name = "user_id")
  private long userId;

  @Column(name = "role_id")
  private long roleId;

  public UserRoleKey() {}

  // hash, equals omitted for brevity
  // getter/setter for userId, roleId omitted for brevity

}

@Entity
@Table(name = "user_role")
class UserRole {

  @EmbeddedId
  private UserRoleKey id;

  @ManyToOne(fetch = FetchType.LAZY)
  @MapsId("userId")
  private User user;

  @ManyToOne(fetch = FetchType.LAZY)
  @MapsId("roleId")
  private Role role;

  @Temporal
  @Column(name = "assigned_at")
  private Date assignedAt;

  public UserRole() {}

  // hash, equals omitted for brevity
  // getter/setter for user, role, assignedAt omitted for brevity

}

其中,两个单独的实体表示为:

@Entity
@Table(name = "user")
class User {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  private String fName;
  private String lName;

  @OneToMany(mappedBy = "user")
  private Set<UserRole> userRoles = new HashSet<>();

  // hash, equals omitted for brevity
  // getter/setter for fName, lName, userRoles omitted for brevity

}

@Entity
@Table(name = "role")
class Role {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  private String name;
  private String alias;

  @OneToMany(mappedBy = "role")
  private Set<UserRole> roleUsers = new HashSet<>();

  // hash, equals omitted for brevity
  // getter/setter for name, alias, roleUsers omitted for brevity

}

每当通过存储库的findAll方法通过API获取Users列表时,返回的UserJSON将无限期地在User上递归,导致异常。用户实体的结果JSON如下所示:

User:
{
  "id": 0,
  "fName": "John",
  "lName": "Doe",
  "userRoles" = [
    {
      "user": {
        // Infinite recursion!
        "id": 0,
        "fName": "John",
        "lName": "Doe",
        "userRoles" = [
          ....
        ]
      },
      "role": {
        "id": 0,
        "name": "Administrator",
        "alias": "admin"
      },
      "assignedAt": "dummy_timestamp"
    }, ...
  ]
}

如果在对位方向使用关系,即通过Role,则会出现相同的问题。

我是不是漏掉了什么?我在Hibernate/JPA/Spring上浏览了大量不同的资源,但我似乎找不到问题所在。

共有2个答案

江俊能
2023-03-14

如果您想获得用户对象没有附加用户角色的用户角色,您可以通过从角色类中删除@OneTo很多(mappdBy="角色")来实现单向关系。

段干靖
2023-03-14

您可以在一个关系上使用@JsonIgnore来打破这个循环。

 类似资料:
  • 我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁:

  • 问题内容: 我的实体中存在双向多对多关系。请参阅以下示例: 当我尝试将其序列化为JSON时,出现以下异常: “ java.lang.IllegalArgumentException:无法处理托管/反向引用’COLLABORATION_TAG’:反向引用类型(java.util.Set)与托管类型(foo.Collaboration)不兼容。 实际上,我知道这很有意义,因为javadoc明确声明您不

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

  • 我正在使用.NET5,并使用EF Core和作为数据库。 我有两个类,他们之间有很多对很多的关系。这些都是从模型迁移到数据库的。DB表示例 迁移: 型号: 所以当我试图更新比赛模型 我得到这个错误 对此有什么可能的解决办法?我想保持我的多对多表UDPAT,因为每次更新时,都可以被删除或添加。 可更新的锦标赛对象示例

  • 我有以下代码: 现在我想再组合一个数组和中的它的值。这是foreach语句中的三个数组。谁能帮我把它加进去。比如我们如何在foreach语句中添加多个。 例如,我想要以下内容: 但是上面的代码给出了。我得到的错误是 分析错误:语法错误,在/homepages/4/d864452909/htdocs/public_html/app/index.php第58行中,意外的“=>”(T_DOUBLE_AR

  • 我正在努力解决hibernate映射问题,即在订单表的主键和带有一些额外列的产品购物车的复合键之间映射一对多关系 产品购物车表具有组合键购物车ID和产品ID 我试着跟踪但没有成功 有人能帮我实现这一点吗?下面是错误消息 原因:组织。冬眠AnnotationException:非法尝试使用mappedBy关联pcoPK定义@JoinColumn。组织pk。冬眠cfg公司。Ejb3JoinColumn