我有一个班级用户:
@Entity
@Table(name = "User")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class User {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "user")
private List<Car> cars;
...
}
和一类车:
@Entity
public class Car {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.EAGER)
@JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
private User user;
...
我有一个有一个用户的汽车类,一个用户可以有多辆汽车。
问题是:
返回汽车列表时,请想象汽车A和B。
汽车A有用户1,汽车B也有用户1。
列表中的伪json序列化:
Car A {
User 1 {
id: 1
Cars: {
Car A: {
User 1 {
id: 1 just shows id 1 - correct in my way of thinking because it already looked into a user 1 and so here it needs to stop the circular dependency.
}
}
}
}
}
Car B {
User 1 {
id: 1 here in my way of thinking it should print the full user because in this level it didnt find one user on top but it seems it takes into consideration the first element of the list (car A) where it already found a User 1? Why?
}
}
我希望汽车B也有完整的用户。
似乎杰克逊的序列化在深度和广度上都有效。
我希望它会深入工作。
因此,基本上,由于返回第二辆车(宽度)中的第一辆车(车A)时已经拜访了用户1,因此它仅显示了车B中的用户1 id。
我希望杰克逊跳到B车时会再次开始循环依赖检查。
我该如何实现?是否可以将杰克逊配置为仅深度而不是广度地执行循环依赖关系检查?
预先感谢您的帮助。
-----工作示例代码-----
package com.guds.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
public class test {
public static void main(String... args) {
User user1 = new User(1, "username 1");
User user2 = new User(2, "username 2");
Car car1 = new Car(1, "car 1", user1);
Car car2 = new Car(2, "car 2", user1);
Car car3 = new Car(3, "car 3", user2);
Car car4 = new Car(4, "car 4", user2);
user1.addGud(car1);
user1.addGud(car2);
user2.addGud(car3);
user2.addGud(car4);
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
List<Car> cars = new ArrayList<>();
cars.add(car1);
cars.add(car2);
ObjectMapper om1 = new ObjectMapper();
String json1 = null;
try {
json1 = om1.writeValueAsString(cars);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(json1);
ObjectMapper om2 = new ObjectMapper();
String json2 = null;
try {
json2 = om2.writeValueAsString(users);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(json2);
}
}
普通车:
package com.guds.test;
public class Car {
private int id;
private String name;
private User user;
public Car(int id, String name, User user) {
this.id = id;
this.name = name;
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
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;
}
}
班级用户:
package com.guds.test;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.util.ArrayList;
import java.util.List;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class User {
private int id;
private String name;
List<Car> cars;
public User(int id, String name) {
this.id = id;
this.name = name;
this.cars = new ArrayList<>();
}
public void addCar(Car car) {
this.cars.add(car);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在此程序的输出的第一行中,您可以看到序列化汽车列表时发生的情况。
我忘了回答我自己的问题。我已经找到了解决方案。
简单的方法是使用@JsonIgnoreProperties。
我需要更改班级:
package com.guds.test;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.util.ArrayList;
import java.util.List;
public class User {
private int id;
private String name;
@JsonIgnoreProperties("user")
List<Car> cars;
public User(int id, String name) {
this.id = id;
this.name = name;
this.cars = new ArrayList<>();
}
}
package com.guds.test;
public class Car {
private int id;
private String name;
@JsonIgnoreProperties("cars")
private User user;
public Car(int id, String name, User user) {
this.id = id;
this.name = name;
this.user = user;
}
}
因此,在User类的情况下,当Jackson开始序列化它时,所有用户属性都将序列化,并且汽车列表和Car对象本身也会被序列化,但是由于我们说在Jackson序列化Car对象时忽略属性用户,不会尝试序列化Car对象内的User。
这样我们就打破了周期。
如果从Car对象开始序列化,也会发生相同的情况。
即使使用@JsonIdentityInfo批注,也不会获取任何信息,而是获取有关该用户的所有信息以及其汽车的所有信息(除了用户,但我们已经拥有关于该用户的信息...),即使它们已经出现在序列化过程。
希望能帮助到你。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句