如何解决json序列化程序中休眠双向映射导致的循环引用?
2022-08-31 11:45:19
我正在编写一个序列化程序将POJO序列化为JSON,但陷入了循环引用问题。在休眠双向一对多关系中,父级引用子引用和子引用回父级引用,在这里我的序列化程序死亡。(请参阅下面的示例代码)
如何打破这个循环?我们能否获取对象的所有者树,以查看对象本身是否存在于其所有者层次结构中的某个位置?还有其他方法可以查找引用是否为循环引用?或任何其他想法来解决这个问题?
我正在编写一个序列化程序将POJO序列化为JSON,但陷入了循环引用问题。在休眠双向一对多关系中,父级引用子引用和子引用回父级引用,在这里我的序列化程序死亡。(请参阅下面的示例代码)
如何打破这个循环?我们能否获取对象的所有者树,以查看对象本身是否存在于其所有者层次结构中的某个位置?还有其他方法可以查找引用是否为循环引用?或任何其他想法来解决这个问题?
我依靠Google JSON通过使用该功能来处理此类问题
假设 A 类和 B 类之间存在双向关系,如下所示
public class A implements Serializable {
private B b;
}
和 B
public class B implements Serializable {
private A a;
}
现在使用 GsonBuilder 获取自定义 Gson 对象,如下所示(注意 setExclusionStrategies 方法)
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == B.class);
}
/**
* Custom field exclusion goes here
*/
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
})
/**
* Use serializeNulls method if you want To serialize null values
* By default, Gson does not serialize null values
*/
.serializeNulls()
.create();
现在我们的循环引用
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
String json = gson.toJson(a);
System.out.println(json);
看看GsonBuilder类
Jackson 1.6(2010 年 9 月发布)具有特定的基于注释的支持来处理此类父/子链接,请参阅 http://wiki.fasterxml.com/JacksonFeatureBiDirReferences。(时光倒流快照)
当然,您已经可以使用大多数JSON处理包(jackson,gson和flex-json至少支持它)排除父链接的序列化,但真正的诀窍是如何将其反序列化(重新创建父链接),而不仅仅是处理序列化端。虽然听起来现在只是排除可能对你有用。
编辑(2012 年 4 月):Jackson 2.0 现在支持真实身份参考(Wayback Snapshot),因此您也可以通过这种方式解决它。