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。
这只是解决您问题的一种方法。
一对多关系导致无限循环使用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。
这只是解决您问题的一种方法。