使用 Set 而不是 List 导致 "Could not write JSON: Infinite recursion" 异常
Using Set instead of List cause "Could not write JSON: Infinite recursion" exception
我在尝试访问端点 http://localhost:8080/categoryOfPermissions. I've researched and found various solutions here (@JsonManagedReference / @JsonBackReference
, @JsonIgnore
, @JsonIdentityInfo
), but none of them seemed to work. Finally, I found an 时收到错误 “无法写入 JSON:无限递归”,说明必须从 Set 更改为 List,以便 @JsonIdentityInfo
解决方案起作用。我测试了它,从 Set 更改为 List 后它真的开始工作了。
我觉得很奇怪,但我发现了更奇怪的事情:从 Set 更改为 List 后,我删除了 @JsonIdentityInfo
注释,一切都继续工作。换句话说,我真正需要做的就是从 Set 更改为 List 以消除异常。没有其他的。不需要任何解决方案:@JsonManagedReference / @JsonBackReference
、@JsonIgnore
、@JsonIdentityInfo
.
下面是产生异常的代码。我所要做的就是将 private Set<Permission> permission
更改为 private List<Permission> permission
.
我想知道为什么,特别是因为我更喜欢使用 Set,以避免 Hibernate 使用“Bags”范式(这可能会导致 some undesirable behaviors)。
Permission.java :
@Entity
@Data
public class Permission{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotBlank
private String name;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_of_permission_id")
private CategoryOfPermission categoryOfPermission;
}
类别Permission.java :
@Entity
@Data
public class CategoryOfPermission{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotBlank
private String name;
@NotNull
@OneToMany(mappedBy = "categoryOfPermission", fetch=FetchType.LAZY)
private Set<Permission> permission;
}
CategoryOfPermissionRepo.java :
public interface CategoryOfPermissionRepo extends CrudRepository<CategoryOfPermission, Integer>{
}
是因为Java
中的Set
使用了equals
契约来判断两个对象是否相同,而[=16=中的方法equals
=] class 实现(使用 lombok
)导致无限递归。
它是 Permission
中 equals
方法的生成代码的一部分
Object this$categoryOfPermission = this.getCategoryOfPermission();
Object other$categoryOfPermission = other.getCategoryOfPermission();
if (this$categoryOfPermission == null) {
if (other$categoryOfPermission != null) {
return false;
}
} else if (!this$categoryOfPermission.equals(other$categoryOfPermission)) {
return false;
}
它是 CategoryOfPermission
class
的生成代码
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof CategoryOfPermission)) {
return false;
} else {
CategoryOfPermission other = (CategoryOfPermission)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$permission = this.getPermission();
Object other$permission = other.getPermission();
if (this$permission == null) {
if (other$permission != null) {
return false;
}
} else if (!this$permission.equals(other$permission)) {
return false;
}
return true;
}
}
}
如你所见 Permission
class 调用 CategoryOfPermission
的 equals
方法 class 和 CategoryOfPermission
调用 equals
的方法Permision
class 这最终导致了 Whosebug 问题!
我在尝试访问端点 http://localhost:8080/categoryOfPermissions. I've researched and found various solutions here (@JsonManagedReference / @JsonBackReference
, @JsonIgnore
, @JsonIdentityInfo
), but none of them seemed to work. Finally, I found an @JsonIdentityInfo
解决方案起作用。我测试了它,从 Set 更改为 List 后它真的开始工作了。
我觉得很奇怪,但我发现了更奇怪的事情:从 Set 更改为 List 后,我删除了 @JsonIdentityInfo
注释,一切都继续工作。换句话说,我真正需要做的就是从 Set 更改为 List 以消除异常。没有其他的。不需要任何解决方案:@JsonManagedReference / @JsonBackReference
、@JsonIgnore
、@JsonIdentityInfo
.
下面是产生异常的代码。我所要做的就是将 private Set<Permission> permission
更改为 private List<Permission> permission
.
我想知道为什么,特别是因为我更喜欢使用 Set,以避免 Hibernate 使用“Bags”范式(这可能会导致 some undesirable behaviors)。
Permission.java :
@Entity
@Data
public class Permission{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotBlank
private String name;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_of_permission_id")
private CategoryOfPermission categoryOfPermission;
}
类别Permission.java :
@Entity
@Data
public class CategoryOfPermission{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotBlank
private String name;
@NotNull
@OneToMany(mappedBy = "categoryOfPermission", fetch=FetchType.LAZY)
private Set<Permission> permission;
}
CategoryOfPermissionRepo.java :
public interface CategoryOfPermissionRepo extends CrudRepository<CategoryOfPermission, Integer>{
}
是因为Java
中的Set
使用了equals
契约来判断两个对象是否相同,而[=16=中的方法equals
=] class 实现(使用 lombok
)导致无限递归。
它是 Permission
equals
方法的生成代码的一部分
Object this$categoryOfPermission = this.getCategoryOfPermission();
Object other$categoryOfPermission = other.getCategoryOfPermission();
if (this$categoryOfPermission == null) {
if (other$categoryOfPermission != null) {
return false;
}
} else if (!this$categoryOfPermission.equals(other$categoryOfPermission)) {
return false;
}
它是 CategoryOfPermission
class
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof CategoryOfPermission)) {
return false;
} else {
CategoryOfPermission other = (CategoryOfPermission)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$permission = this.getPermission();
Object other$permission = other.getPermission();
if (this$permission == null) {
if (other$permission != null) {
return false;
}
} else if (!this$permission.equals(other$permission)) {
return false;
}
return true;
}
}
}
如你所见 Permission
class 调用 CategoryOfPermission
的 equals
方法 class 和 CategoryOfPermission
调用 equals
的方法Permision
class 这最终导致了 Whosebug 问题!