我有一个Spring应用程序,其中包含两个具有多对多关系的实体。有学生和团体。学生可以成为许多团体的一部分,一个团体可以有很多学生。
学生模特
@Entity
@Table(name = "STUDENTS")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Student extends AbstractUser {
//Fields
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class)
@JoinTable(name = "GROUPS_STUDENTS",
joinColumns = { @JoinColumn(name = "student_id") },
inverseJoinColumns = { @JoinColumn(name = "group_id") })
private List<Group> groups = new ArrayList<Group>();
//Constructors
public Student(String password, String firstName, String lastName, String email){
super(password, firstName, lastName, email);
}
public Student(){
}
//Setters and getters
public List<Group> getGroups() {
return groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
}
群组模型
@Entity
@Table(name = "GROUPS")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Group implements Item, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false, unique = true)
private String name;
@Column(name = "year", nullable = false, length = 1)
private int year;
@ManyToMany(mappedBy = "groups", targetEntity = Student.class)
private List<Student> students;
public Group(String name, int yearOfStudy) {
this.setName(name);
this.setYear(yearOfStudy);
}
...
}
问题在于,当我向所有学生发出请求时,如果2名学生在同一组中,则他们出现在层次结构中而不是一个接一个。我的意思是JSON太深了。我不知道如何准确解释,但我会举一个例子。
如何显示
[
{
"id": 2,
"password": "$2a$10$bxieGA7kWuEYUUMbYNiYo.SbGpo7X5oh8ulUsqCcrIR2cFN2HiQP2",
"firstName": "First",
"lastName": "Last",
"email": "name@mail.com",
"groups": [
{
"id": 1,
"name": "G1",
"year": 0,
"users": [
2,
{
"id": 1,
"password": "$2a$10$9pfTdci7PeHtzxuAxjcOsOjPSswrU35/JOOeWPpgVhJI4tD2YpZdG",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@mail.com",
"groups": [
1
]
}
]
}
]
},
1
]
&#13;
应该如何显示
{
"id": 2,
"password": "$2a$10$bxieGA7kWuEYUUMbYNiYo.SbGpo7X5oh8ulUsqCcrIR2cFN2HiQP2",
"firstName": "First",
"lastName": "Last",
"email": "name@mail.com",
"groups": [
{
"id": 1,
"name": "G1",
"year": 0,
}
]
},
{
"id": 1,
"password": "$2a$10$9pfTdci7PeHtzxuAxjcOsOjPSswrU35/JOOeWPpgVhJI4tD2YpZdG",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@mail.com",
"groups": [
{
"id": 1,
"name": "G1",
"year": 0
}]
}
]
&#13;
你知道如何解决这个问题吗?我不知道如何描述我的问题,以及为什么我还没有找到解决方案。任何帮助将非常感谢。谢谢。
答案 0 :(得分:3)
使用@JsonIgnoreProperties
注释是另一种选择:
@Entity
public class Student extends AbstractUser {
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class)
@JoinTable(name = "GROUPS_STUDENTS",
joinColumns = { @JoinColumn(name = "student_id") },
inverseJoinColumns = { @JoinColumn(name = "group_id") })
@JsonIgnoreProperties("students")
private List<Group> groups = new ArrayList<Group>();
}
@Entity
public class Group implements Item, Serializable {
@ManyToMany(mappedBy = "groups", targetEntity = Student.class)
@JsonIgnoreProperties("groups")
private List<Student> students;
}
在此处找到@JsonManagedReference
+ @JsonBackReference
,@JsonIdentityInfo
和@JsonIgnoreProperties
之间的比较:http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
答案 1 :(得分:0)
要解决杰克逊无限递归问题,您可以使用.row{
transition-property: top;
transition-duration:0.5s;
}
,@JsonManagedReference
。
@JsonManagedReference是引用的前向部分 - 那个 正常序列化。
@JsonBackReference是后面的部分 参考 - 它将从序列化中省略。
在此处查找更多详情:http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
@JsonBackReference
答案 2 :(得分:0)
如果您希望能够动态定义必须序列化的内容,您可以尝试我根据此处提出的问题开发的jackson插件:
https://stackoverflow.com/a/28245875/869225
这也帮助我进行反向推理。
答案 3 :(得分:0)
我已经解决了。我做了一个自定义序列化程序。所以在第一组中,我会通过设置自定义注释序列化学生 @JsonSerialize(using = CustomStudentSerializer.class)
<强> CustomStudentSerializer 强>
public class CustomStudentSerializer extends StdSerializer<List<Student>> {
public CustomStudentSerializer() {
this(null);
}
public CustomStudentSerializer(Class<List<Student>> t) {
super(t);
}
@Override
public void serialize(
List<Student> students,
JsonGenerator generator,
SerializerProvider provider)
throws IOException, JsonProcessingException {
List<Student> studs = new ArrayList<>();
for (Student s : students) {
s.setGroups(null);
studs.add(s);
}
generator.writeObject(studs);
}
}
对团体做了同样的事情。当关系已经嵌套时,我刚刚删除了学生/组组件。现在它的工作正常。
我花了一些时间来解决这个问题,但我发布在这里因为它也可以帮助其他人。
答案 4 :(得分:0)
或者您可以使用DTO(数据传输对象)类。这些是简单的代码类,您可以在sendind数据时根据需要进行设置。例如,对于您的情况,您可以:
UserDTO.java:
import java.util.List;
public class UserDTO {
private int id;
private String password;
private String firstName;
private String lastName;
private String email;
private List<GroupDTO> groups;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<GroupDTO> getGroups() {
return groups;
}
public void setGroups(List<GroupDTO> groups) {
this.groups = groups;
}
}
GroupDTO.java
package temp;
public class GroupDTO {
private int id;
private String name;
private int year;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
}
这样您就可以自定义要在json文件中发送的信息。
假设您有一个User类,并且您希望向所有用户发送信息:
List<StudentDTO> response = new ArrayList<StudentDTO>(); //List to be send
List<Student> students = bussinessDelegate.findAllStudents(); //Or whatever you do to get all students
for (int i = 0; i < students.size(); i++) {
Student student = students.get(i);
StudentDTO studentDTO = new StudentDTO(); //Empty constructor
studentDTO.setEmail(student.getEmail());
studentDTO.setFirstName(student.getFirstName());
studentDTO.setLastName(student.getLastName());
studentDTO.setId(student.getId());
studentDTO.setPassword(student.getPassword());
List<Group> studentGroups = student.getGroups();
List<GroupDTO> studentGroupsDTO = new ArrayList<GroupDTO>();
for (int j = 0; j < studentGroups.size(); j++) {
Group group = studentGroups.get(j);
GroupDTO groupDTO = new GroupDTO();
groupDTO.setId(group.getId());
groupDTO.setName(group.getName());
groupDTO.setYear(group.getYear());
studentGroupsDTO.add(groupDTO);
}
studentDTO.setGroups(studentGroupsDTO);
response.add(studentDTO);
}
//Here you have your response list of students ready to send`