杰克逊 - 反序列化失败了循环依赖 [英] Jackson - deserialization fails on circular dependencies

查看:227
本文介绍了杰克逊 - 反序列化失败了循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以我正试图用杰克逊json转换器测试一些东西。
我正在尝试模拟图形行为,因此这些是我的POJO实体

  @JsonIdentityInfo(generator = ObjectIdGenerators .PropertyGenerator.class,property =id)
public class ParentEntity实现java.io.Serializable
{
private String id;
private字符串描述;
private ParentEntity parentEntity;
private List< ParentEntity> parentEntities = new ArrayList< ParentEntity>(0);
private List< ChildEntity> children = new ArrayList< ChildEntity>(0);
// ... getter and setters
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =id)
public class ChildEntity implements java.io.Serializable
{
private String id;
private字符串描述;
私人ParentEntity父母;
// ... getter and setters
}

标签是必需的为了避免序列化上的异常。
当我尝试序列化一个对象(文件或简单的字符串)时,一切正常。但是,当我尝试反序列化对象时,它会抛出异常。这是一个简单的测试方法(为了简单起见省略了try / catch)

  {
//创建一些实体,分配他们有些价值
ParentEntity pe = new ParentEntity();
pe.setId(1);
pe.setDescription(第一父母);

ChildEntity ce1 = new ChildEntity();
ce1.setId(1);
ce1.setDescription(第一个孩子);
ce1.setParent(pe);

ChildEntity ce2 = new ChildEntity();
ce2.setId(2);
ce2.setDescription(第二个孩子);
ce2.setParent(pe);

pe.getChildren()。add(ce1);
pe.getChildren()。add(ce2);

ParentEntity pe2 = new ParentEntity();
pe2.setId(2);
pe2.setDescription(第二父母);
pe2.setParentEntity(pe);
pe.getParentEntities()。add(pe2);

//序列化
ObjectMapper mapper = new ObjectMapper();
文件f =新文件(parent_entity.json);
//写入文件
mapper.writeValue(f,pe);
//写入字符串
String s = mapper.writeValueAsString(pe);
//反序列化
//从文件中读取
ParentEntity pe3 = mapper.readValue(f,ParentEntity.class);
//从字符串中读取
ParentEntity pe4 = mapper.readValue(s,ParentEntity.class);
}

这是抛出的异常(当然,重复两次)

  com.fasterxml.jackson.databind.JsonMappingException:已经有id(java.lang.String)的POJO [com.fasterxml.jackson。 annotation.ObjectIdGenerator$IdKey@3372bb3f](通过引用链:ParentEntity [children]  - > java.util.ArrayList [0]  - > ChildEntity [id])
... stacktrace .. 。
引起:java.lang.IllegalStateException:已经有id的POJO(java.lang.String)[com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey@3372bb3f]
... stacktrace。 ..

那么,问题的原因是什么?我该如何解决?我需要一些其他注释吗?

解决方案

实际上,问题似乎是id属性。因为两个不同实体的属性名称相同,所以在反序列化期间存在一些问题。不知道它是否有意义,但我解决了将ParentEntity的 JsonIdentityInfo 标签更改为



<$的问题p $ p> @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property =id,scope = ParentEntity.class))

当然,我也改变了ChildEntity的范围,其中 scope = ChildEntity.class
,如建议的那样这里



我愿意接受新的答案和建议。


Ok, so I'm trying to test some stuffs with jackson json converter. I'm trying to simulate a graph behaviour, so these are my POJO entities

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ParentEntity implements java.io.Serializable
{   
    private String id;
    private String description;
    private ParentEntity parentEntity;
    private List<ParentEntity> parentEntities = new ArrayList<ParentEntity>(0);
    private List<ChildEntity> children = new ArrayList<ChildEntity>(0);
    // ... getters and setters
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ChildEntity implements java.io.Serializable
{
    private String id;
    private String description;
    private ParentEntity parent;
    // ... getters and setters
}

The tags are required in order to avoid exception on serialization. When I try to serialize an object (both on a file or on a simple string) all works fine. However, when I try to deserialize the object, it throws an exception. This is the simple test method (try/catch omitted for simplicity)

{
    // create some entities, assigning them some values
    ParentEntity pe = new ParentEntity();
    pe.setId("1");
    pe.setDescription("first parent");

    ChildEntity ce1 = new ChildEntity();
    ce1.setId("1");
    ce1.setDescription("first child");
    ce1.setParent(pe);

    ChildEntity ce2 = new ChildEntity();
    ce2.setId("2");
    ce2.setDescription("second child");
    ce2.setParent(pe);

    pe.getChildren().add(ce1);
    pe.getChildren().add(ce2);

    ParentEntity pe2 = new ParentEntity();
    pe2.setId("2");
    pe2.setDescription("second parent");
    pe2.setParentEntity(pe);
    pe.getParentEntities().add(pe2);

    // serialization
    ObjectMapper mapper = new ObjectMapper();
    File f = new File("parent_entity.json");
    // write to file
        mapper.writeValue(f, pe);
    // write to string
    String s = mapper.writeValueAsString(pe);
    // deserialization
    // read from file
    ParentEntity pe3 = mapper.readValue(f,ParentEntity.class);
    // read from string
    ParentEntity pe4 = mapper.readValue(s, ParentEntity.class);         
}

and this is the exception thrown (of course, repeated twice)

com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey@3372bb3f] (through reference chain: ParentEntity["children"]->java.util.ArrayList[0]->ChildEntity["id"])
...stacktrace...
Caused by: java.lang.IllegalStateException: Already had POJO for id (java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey@3372bb3f]
...stacktrace...

So, what is the cause of the problem? How can I fix it? Do I need some other annotation?

解决方案

Actually, it seems that the problem was with the "id" property. Because the name of the property is equal for the two different entities, there were some problems during deserialization. Don't know if it makes sense at all, but I solved the problem changing the JsonIdentityInfo tag of ParentEntity to

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = ParentEntity.class))

Of course, I also changed the scope of ChildEntity with scope=ChildEntity.class as suggested here

I'm open to new answer and suggestions by the way.

这篇关于杰克逊 - 反序列化失败了循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆