杰克逊的循环依赖只是通过深度而不是通过深度和广度

cyp:

我有一个班级用户:

@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;
    }
}

在此程序的输出的第一行中,您可以看到序列化汽车列表时发生的情况。

cyp:

我忘了回答我自己的问题。我已经找到了解决方案。

简单的方法是使用@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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

通过深度学习从PDF提取短语

通过深度学习从表单中提取文本的最佳方法?

JS通过深度嵌套的对象对JSON进行归类和分组

在Python和Keras中通过深度学习执行照明估计后,如何显示色彩校正的图像?

Haskell通过深度优先顺序遍历来标记二叉树

如何从通过深度特征合成创建的feature_def中选择特征

通过深层财产收集

解析与杰克逊深度嵌套的JSON属性

消除对杰克逊的依赖

是否可以在打字稿中跳过深度级别?

使用杰克逊通过json文件的键选择值

如何通过杰克逊进行字符串验证?

使用杰克逊序列化递归对象达一定深度

杰克逊:JsonIdentityInfo序列化了唯一一个孩子的深度

如何通过深层哈希键对值进行分组?

Vue,Composition API:如何从反应式转换中跳过深度嵌套的属性?

阿帕奇骆驼和杰克逊

杰克逊:财产秩序和继承

杰克逊的@ JsonView,@ JsonFilter和Spring

杰克逊-结合@JsonValue和@JsonSerialize

杰克逊的RESTEasy和ContextResolver <ObjectMapper>

杰克逊和多接口继承

气流:并发深度优先,而不是广度优先?

适用于App Store和Google Play的网址格式,用于通过深层链接安装应用

通过杰克逊同一水平写作JSON多个值

杰克逊抛出JSONMappingException不能强制转换为java.lang.Comparable(通过引用链***)

我怎样才能通过JSON重复使用杰克逊的对象?

通过父类的字段值反序列化与杰克逊小类

如何通过“ jackson2ObjectMapperBuilder”在杰克逊中启用“全局默认类型”