Spring Data JPA @OneToMany 无限循环异常

Mer*_*erv 6 json hibernate infinite-loop spring-data-jpa

使用Spring Data JPA和 hibernate 作为提供程序时,OneToMany 关系导致无限循环

这里的问题不是异常的类型而是导致此异常的无限循环

无限循环

我尝试了@JsonIgnoreProperties,这给了我另一个错误=> “无法编写JSON:找不到类org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer的序列化器,并且没有发现创建BeanSerializer的属性”

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

有人说使用 @JsonManagedReference 和 @JsonBackReference 确实会停止递归,但当我想要“myUser”实体的对象时,会从我需要的结果中排除该对象(“myUser”实体中的 UserGroup)。

另一个说的是关于重写 ToString 方法,但我没有这样做。

另一位解释了为什么存在无限循环,并建议不要这样做。我引用“尝试创建 DTO 或值对象(简单 POJO),而不从返回的模型中循环,然后返回它。”

@JsonIgnore 和 @JsonBackReference 之间的区别,@JsonManagedReference解释了区别,但这样做我会遇到与第一个相同的问题

“我的用户”实体

@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;
Run Code Online (Sandbox Code Playgroud)

“用户组”实体

@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;
Run Code Online (Sandbox Code Playgroud)

Don*_*asa 1

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

根据您列举的解决方案,我建议您仍然应该使用@JsonBackReference@JsonManagedReference防止实体上的递归,并且为了解决您的问题,您可以尝试使用映射器(MapStruck)并在检索期间将 userGroup 详细信息映射到 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;
}
Run Code Online (Sandbox Code Playgroud)

映射器(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);
}
Run Code Online (Sandbox Code Playgroud)

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

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