Spring 数据JPA @OneToMany 无限循环异常

Spring Data JPA @OneToMany infinite loop exception

一对多关系导致无限循环使用Spring数据JPA与休眠作为提供者

这里的问题不是异常的类型而是导致这个异常的死循环

我尝试了@JsonIgnoreProperties,这给了我另一个错误=> 'Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer'

引用该解决方案的 post 没有解决我的问题的解决方案。

One 说使用 @JsonManagedReference 和 @JsonBackReference 确实停止了递归但从我需要的结果中排除了对象('myUser' 实体中的 UserGroup)想要一个 'myUser' 实体的对象。

另一个 说的是覆盖 ToString 方法,我没有这样做。

另一个解释了为什么会出现无限循环,并建议不要这样做。我引用"Try to create DTO or Value Object (simple POJO) without cycles from returned model and then return it."

和这个 解释了区别但是这样做我会遇到和第一个一样的问题

'myUser'实体

@Entity
public class MyUser {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String firstName;
  private String lastName;
  private String email;
  private Integer age;

  //@JsonIgnoreProperties({"myUsers"})
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "userGroupId")
  private UserGroup userGroup;

'UserGroup'实体

@Entity
public class UserGroup {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Integer groupOrder;
    @OneToMany
    (
        mappedBy = "userGroup", 
        cascade = CascadeType.ALL, 
        orphanRemoval = true
    )
    private List<MyUser> myUsers;

您需要在 @OneToMany

添加 @JsonIgnore 注释

像这样

@JsonIgnore   
@OneToMany
    (
        mappedBy = "userGroup", 
        cascade = CascadeType.ALL, 
        orphanRemoval = true
    )
    private List<MyUser> myUsers;

按如下方式更改 MyUser class 中的 getUserGroup() 方法。

@Entity
public class MyUser 
{    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;
    private Integer age;

    //@JsonIgnoreProperties({"myUsers"})
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "userGroupId")
    private UserGroup userGroup;

    public UserGroup getUserGroup() 
    {
        userGroup.setMyUsers(null);
        return userGroup;
    }
}

我想我明白了你的问题。您想要获取 MyUser 包括 userGroup 数据但没有 循环引用 .

根据您列举的解决方案,我建议您仍应使用 @JsonBackReference@JsonManagedReference 防止递归 在您的实体和解决方案中关于您的问题,您可以尝试使用映射器 (MapStruck) 并在从服务检索数据期间将用户组详细信息映射到 DTO。

DTO:

public class MyUserDto {
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    private Integer age;
    private UserGroupDto userGroupDto;
}

public class UserGroupDto {
    private Long id;
    private Integer groupOrder;
}

映射器(MapStruck):

@Mapper(componentModel = "spring")
public interface MyUserMapper {

    MyUserMapper INSTANCE = Mappers.getMapper(MyUserMapper.class);
    
    UserGroupDto userGroupToDto(UserGroup userGroup);

    @Mapping(source = "myUser.userGroup", target = "userGroupDto")
    MyUserDto myUserToDto(MyUser myUser);
}

repository 检索数据后,您可以调用 myUserToDto 方法将实体映射到 DTO。

这只是解决您问题的一种方法。