我正在开发一个springboot应用程序。我有两个实体类,组和用户。我还在Group类(拥有实体)和User类中定义了@ManyToMany关系,这样我就可以获取用户所属的所有组。不幸的是,由于以下错误,我无法创建新组或新用户;
{
"timestamp": "2022-09-09T20:29:22.606+00:00",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'application/json;charset=UTF-8' not supported"
}当我试图通过调用user.get().getGroups();获取用户所属的所有组时,会出现堆栈溢出错误。
注意:目前,我在Group类和User类中分别拥有@JsonManagedReference和@JsonBackReference。我还尝试在两个类中添加@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id"),但这也不起作用。向@JsonManagedReference和@JsonBackReference添加value参数也不起作用,如下所示。我做错了什么?我遗漏了什么?
这是我的组实体类
@Table(name = "`group`") // <- group is a reserved keyword in SQL
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@JsonView(Views.Public.class)
private String name;
private Integer maximumMembers;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinTable(name = "group_user", joinColumns = @JoinColumn(name = "group_id"), inverseJoinColumns = @JoinColumn(name = "user_id"))
@JsonView(Views.Public.class)
@JsonManagedReference(value = "group-member")
private Set<User> groupMembers;
}这是我的用户实体类
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonView(Views.Public.class)
private Long id;
@JsonView(Views.Public.class)
private String nickname;
@JsonView(Views.Public.class)
private String username; // <- Unique user's phone number
private String password;
@ElementCollection(targetClass = ApplicationUserRole.class)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
@Column(name = "role")
private Set<ApplicationUserRole> roles;
@ManyToMany(mappedBy = "groupMembers", fetch = FetchType.LAZY, targetEntity = Group.class)
@JsonBackReference(value = "user-group")
private Set<Group> groups;
}发布于 2022-09-12 14:31:05
我找到了这个问题的永久解决方案。对于其他面临类似问题的人来说,这就是我所发现的。首先,我的实体类有@Data Lombok注释。我删除了这一点,因为@Data注释几乎总是加载集合,即使您有FetchType.LAZY。
您可以阅读更多关于为什么不应该用@Data注释实体类的文章,https://www.jpa-buddy.com/blog/lombok-and-jpa-what-may-go-wrong/
删除这个注释后,我从关系的两边(两个实体)中删除了@JsonManagedReference和@JsonBackReference。然后,我只将@Jsonignore添加到引用端(User类)。这解决了两件事
在此之后,我们还有最后一个问题。当我们试图从api中读取一个用户时,我们会得到一个没有关联的组列表的用户,因为我们在用户列表中有@JsonIgnore。为了解决这个问题,我让控制器返回一个新对象。因此,在从我的服务中获取用户之后,我将其映射到一个新的数据传输对象,即我在控制器中返回这个对象。
从这里开始,我使用@JsonView过滤我的答复。
这就是我的类的样子,注意注释中没有@Data。
集团
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
@Table(name = "`group`") // <- group is a reserved keyword in SQL
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Integer maximumMembers;
@ManyToMany(fetch = FetchType.EAGER,
cascade = {CascadeType.MERGE, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(name = "group_user",
joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
@JsonView(UserViews.PublicUserDetails.class)
private Set<User> groupMembers = new HashSet<>();
} 用户
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonView(UserViews.PublicUserDetails.class)
private Long id;
@JsonView(UserViews.PublicUserDetails.class)
private String nickname;
@JsonView(UserViews.PublicUserDetails.class)
private String username; // <- Unique user's phone number
private String password;
@ElementCollection(targetClass = ApplicationUserRole.class)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
@Column(name = "role")
@JsonView(UserViews.PublicUserDetails.class)
private Set<ApplicationUserRole> roles;
@JsonIgnore
@ManyToMany(mappedBy = "groupMembers", fetch = FetchType.LAZY, targetEntity = Group.class)
private Set<Group> groups = new HashSet<>();
}在用户控制器中获取用户的方法
@GetMapping("/get-groups")
public ResponseEntity<UserRequestResponseDTO> getWithGroups(@RequestParam(name = "userId") Long userId) {
User user = userService.getWithGroups(userId);
UserRequestResponseDTO response = UserRequestResponseDTO.builder()
.nickname(user.getNickname())
.username(user.getUsername())
.groups(user.getGroups())
.build();
return ResponseEntity.ok().body(response);
}希望这能帮到别人
https://stackoverflow.com/questions/73667314
复制相似问题