【问题标题】:Spring is not serializing HashMap AttributeSpring 没有序列化 HashMap 属性
【发布时间】:2016-02-03 10:36:06
【问题描述】:

首先,我使用的是 Spring MVC

我有一个“技能”模型类,我在其中放置了@JsonIgnoreProperties

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

我使用它是因为存在多对多或多对一或一对多关系,如果没有此属性,它会导致 StackOverFlowException(无限错误)。一个技能可以有很多技能,所以有一种递归。

我为“Skill”实现了一个名为“SkillBean”的子类,它还有一个属性“checked”,该属性仅与应用程序相关,而不与数据库相关。

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

我正在使用 BeanUtils.copyProperties() 将 Skill-Object 复制到 SkillBean-Object 中。这工作正常。我需要重新排序技能,因为目前我首先获得最低的 Child-Skill 而不是它的父级。为此,我正在尝试重新排序对象并尝试在列表中构建一棵树。每项技能都有一组子项。

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
}

【问题讨论】:

  • 我不太明白你的问题。这是 JPA 映射、JSON 映射还是您的代码的某些部分(可能某些部分您还没有向我们展示)的问题?您是否调试过您的代码以查看它开始出错的地方?
  • 顺便说一句,属性名称“berufsgruppes”让我不寒而栗;)
  • 我调试了它,技能的listentry有一个带有subkills的hashMap,但是序列化似乎出错了,我不知道为什么或如何找到错误。所以我不认为这是我的代码的一部分。所以老实说,我不知道它是 JPA 还是 JSON 映射。模型类由 hibernate 生成。我知道你的意思:P
  • 我假设您正在通过 JPA 加载技能,然后将其转换为一些 JSON 对象。你能检查一下 JPA 加载了什么,即子技能是否仍然存在?除此之外,一些 JSON 库不喜欢没有特殊处理的自引用(至少这是我对 Jackson 的经验),因此您的 JSON 映射配置可能有问题(@JsonIgnoreProperties({..."skills"}) 可能是问题 - 子技能设置为忽略)。
  • 我通过 CrudRepository Iterable&lt;Skill&gt; itSkills = skillDAO.findAll(); List&lt;Skill&gt; allSkills = new ArrayList&lt;Skill&gt;(); itSkills.forEach(allSkills::add); 获得了 DAO 的所有技能

标签: java spring serialization jackson


【解决方案1】:

最后,我得到了这个:

  1. 忽略技能的父级或忽略技能的子级以避免无限递归。 在某些情况下,您不需要忽略其中之一。如果你没有那么多数据,它可以工作。我说的是 150 个节点,每个节点都知道它的父/子。

  2. 我正在使用自定义 sql 查询查询从下到上的最低技能路径。

  3. 我将我所有的技能都放在地图的最高级别。这意味着,我可以使用我所有的技能,因为(正如我所说)每个节点都知道他的孩子。

  4. 我正在我的地图中从上到下搜索,并根据我已经得到的路径删除我不需要的所有引用。

整个代码有点复杂,我使用递归使其不那么复杂。最后我对这个解决方案不太满意,因为其中有很多循环,到目前为止我在性能问题上遇到了一些麻烦。

我需要发现是数据库查询问题还是循环引起的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-16
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 2017-01-08
    相关资源
    最近更新 更多