簡體   English   中英

兩個對象之間的父子關系導致 JSON StackOverflowError

[英]Parent-child relation between two objects causes JSON StackOverflowError

我試圖在某些對象之間實現父子關系,但遇到了一些麻煩。

就我而言,我試圖將對象存儲在其他對象中(例如,容器存儲多個項目或其他帶有項目的容器)。 棘手的部分是存儲中的每個對象都應該能夠分辨出它最外層的父對象是什么。 雖然這似乎在我的內存數據庫中工作(目前使用 h2),但嘗試獲取我所有存儲項的 JSON 表示會給出這個(我返回一個List<StorageUnit> ):

無法寫入 JSON:無限遞歸 (StackOverflowError); 嵌套異常是 com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)(通過引用鏈:java.util.ArrayList[0]->com.warehousing.storage.FixedContentsCase["contents"]->java.util .ArrayList[0]->com.warehousing.storage.FixedContentsCase["contents"]->...

以下是課程:

存儲單元

@Entity
@Inheritance
public abstract class StorageUnit {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   private Long id;
   @ManyToOne
   private Location location;
   protected Long parentContainerId;
   // <getters & setters> 
   public abstract List<StorageUnit> getContents();
}

固定內容案例


@Entity
public class FixedContentsCase extends StorageUnit {
    @OneToMany
    private List<Item> items; 

    public FixedContentsCase() {
        super();
        items = new ArrayList<>();
    }
    // <getters & setters> 
    @Override
    public List<StorageUnit> getContents() {
        // Return the case itself and its contents
        List<StorageUnit> contents = new ArrayList<>(Arrays.asList(this));
        for (StorageUnit item : items) 
            contents.addAll(item.getContents());
        return contents;
    }   
}

物品

@Entity
public class Item extends StorageUnit {

    private String description;

    public Item() {
        super();
        this.description = "";
    }
    // <getters & setters> 
    @Override
    public List<StorageUnit> getContents() {
        return Arrays.asList(this);
    }   
}

我試圖用@JsonIgnoreProperties("parentContainerId")注釋StorageUnit類,但沒有用。 @JsonIgnore注釋parentContainerId也沒有幫助。 我還嘗試注釋 getter 而不是屬性本身(如下所示)。 有沒有辦法解決這個問題,或者是否需要進行某種設計更改? 謝謝!

使用 Jackson 這絕對可以通過 @JsonIgnore 或提到的 DTO 方法 BugsForBreakfast 之類的注釋來實現。

我創建了一個 jackson MixIn 處理程序來允許動態過濾,我用它來避免 DTO 的樣板

https://github.com/Antibrumm/jackson-antpathfilter

自述文件中的示例應該顯示它是如何工作的,以及它是否適合您。

您的問題是您將存儲單元本身添加到其內容列表中,如果向下遍歷樹,則會導致無限遞歸。 解決方案:使用引用並且只序列化對象一次,使用@JsonIdentityInfo@JsonIdentityReference

public class MyTest {

    @Test
    public void myTest() throws JsonProcessingException {
        final FixedContentsCase fcc = new FixedContentsCase();
        fcc.setId(Long.valueOf(1));
        final Item item = new Item();
        item.setId(Long.valueOf(2));
        item.setDescription("item 1");
        fcc.getItems().add(item);
        final ObjectMapper om = new ObjectMapper();
        System.out.println(om.writeValueAsString(fcc));
    }
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = false)
class Item extends StorageUnit {

    ...
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = false)
class FixedContentsCase extends StorageUnit {

    ...
}

abstract class StorageUnit {

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM