2016-02-03 67 views
0

首先,我使用了Spring MVCSpring未序列化HashMap屬性

我有一個「技能」 -modelclass,在那裏我把@JsonIgnoreProperties

@JsonIgnoreProperties({"personSkills","berufsgruppes","skills"}) 
@JsonPropertyOrder({"idSkill", "name", "levelBezeichnung", "skill"}) 

我使用它,因爲有很多一對多或多對一的一對一或一對多關係,如果沒有這個屬性,它會導致StackOverFlowException(無限錯誤)。一個技能可以有很多技能,所以有一種遞歸。

我爲名爲「SkillBean」的「Skill」實現了一個子類,它具有一個「已檢查」的屬性,與應用程序不僅適用於數據庫。

public class Skill implements java.io.Serializable { 

private Set<Skill> skills = new HashSet<Skill>(0); 
... 
@OneToMany(fetch = FetchType.LAZY, mappedBy = "skill") 
public Set<Skill> getSkills() { 
    return this.skills; 
} 
public void setSkills(Set<Skill> skills) { 
    this.skills = skills; 
} 

public class SkillBean extends Skill implements Serializable{ 

public boolean checked; 

public SkillBean() { 
} 

public SkillBean(Skill skill, boolean checked) { 
    this.checked = checked; 
} 
public boolean isChecked() { 
    return checked; 
} 

public void setChecked(boolean checked) { 
    this.checked = checked; 
} 
} 

IM使用BeanUtils.copyProperties()到技能對象複製到一個SkillBean - 對象。這工作正常。我需要對技能進行重新排序,因爲目前我得到的是最低的兒童技能,而不是其父。爲此,我嘗試重新排列對象並嘗試在列表中構建樹。每項技能都有一組兒童。

private ArrayList<SkillBean> formatSkillMap(HashMap<Integer, SkillBean> map) { 
    Map<Integer, SkillBean> tempSkills = (Map<Integer, SkillBean>) map.entrySet().stream().filter(p -> p.getValue().getSkill() == null) 
      .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 

    ArrayList<SkillBean> list = new ArrayList<SkillBean>(tempSkills.values()); 

    for (int i = 0; i < list.size(); i++) { 
     SkillBean sb = list.get(i); 
     tempSkills = (Map<Integer, SkillBean>)  map.entrySet().stream().filter(p -> p.getValue().getSkill() != null) 

       .filter(p -> p.getValue().getSkill().getIdSkill() == sb.getIdSkill()).collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 
     Set<Skill> test = new HashSet<Skill>(tempSkills.values()); 
     list.get(i).setSkills(test); 
    } 
    return list; 

不過這個名單犯規返回子技能誰能告訴我,爲什麼次技巧不序列化?當我返回這個家長技能的子集時,他們的單項技能被序列化。

0: { 
"idSkill": 34 
"name": "Methodik" 
"levelBezeichnung": { 
    "@id": 1 
    "idLevelBezeichnung": 1 
    "bezeichnung": "Standard" 
    "handler": {} 
    "hibernateLazyInitializer": {} 
}- 
"checked": true 
} 

沒有重新排序它看起來像這樣,但問題是ID = 34的技能是父母技能,9是單項技能。我想完全相反。可能有三個層次。

9: { 
"idSkill": 9 
"name": "Standards" 
"levelBezeichnung": { 
    "@id": 1 
    "idLevelBezeichnung": 1 
    "bezeichnung": "Standard" 
    "handler": {} 
    "hibernateLazyInitializer": {} 
}- 
"skill": { 
    "idSkill": 34 
    "name": "Methodik" 
    "levelBezeichnung": 1 
}- 
"checked": true 
} 
+0

我不太明白你的問題。這是JPA映射,JSON映射還是代碼的一部分問題(也許有些部分你還沒有向我們展示)?你調試了你的代碼,看看它開始出錯的地方嗎? – Thomas

+0

順便說一句,屬性名稱「berufsgruppes」讓我不寒而慄;) – Thomas

+0

我調試它,該技能的監聽有一個帶有subkills的哈希映射,但序列化似乎出錯了,我不知道爲什麼或如何找到錯誤。所以我不認爲這是我的代碼的一部分。 老實說,我不知道它是JPA還是JSON映射。 模型類由hibernate生成。我知道你的意思:P – Andy

回答

0

最後,我結束了這一點:

  1. 忽略技能的父母或忽略技能的孩子會造成死循環。 在某些情況下,您不需要忽略其中的一個。如果你沒有那麼多的數據,它可以工作。我說的是每個節點都知道其父母/子女的150個節點。

  2. 我正在查詢自定義sql查詢的最低技能從下到上的路徑。

  3. 我把我所有的技能都放在地圖的最高層。這意味着,我可以使用我所有的技能,因爲(如我所說)每個節點都知道他的孩子。

  4. 我在從我的地圖上從上到下搜索,並根據我已經得到的路徑刪除所有不需要的引用。

整個代碼有點複雜,我使用遞歸來減少它的複雜性。最後,我對這個解決方案並不滿意,因爲它有很多循環,到目前爲止,我在性能問題上遇到了一些麻煩。

我需要發現它是數據庫查詢問題還是由循環造成的問題。