【发布时间】: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<Skill> itSkills = skillDAO.findAll(); List<Skill> allSkills = new ArrayList<Skill>(); itSkills.forEach(allSkills::add);获得了 DAO 的所有技能
标签: java spring serialization jackson