Json(fasterxml)stackoverflowexception

尝试序列化类别时,我得到一个stackoverflow。

例外

警告:StandardWrapperValve [dispatcher]:servlet调度程序的Servlet.service()在java.lang.ClassLoader.defineClass(ClassLoader.java:760)的java.lang.ClassLoader.defineClass1(本机方法)中抛出exceptionjava.lang.StackOverflowError at org.apache.felix.framework.BundleWiringImpl $ BundleClassLoader.findClass(BundleWiringImpl.java:2279)位于org.apache.felix.framework.BundleWiringImpl的org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)。在com.fasterxml的java.lang.ClassLoader.loadClass(ClassLoader.java:357)的org.apache.felix.framework.BundleWiringImpl $ BundleClassLoader.loadClass(BundleWiringImpl.java:1955)访问$ 400(BundleWiringImpl.java:75)。 jackon.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:660),位于com.fasterxml.jackson.databind.ser的com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)。 impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:1 00)com的com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:21)at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)at com位于com.fasterxml.jackson.databind的com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)中的.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541) .ser.BeanSerializer.serialize(BeanSerializer.java:152)

Category.java

@Entity public class Category implements DataObject, Serializable { @Id @GeneratedValue private Long id; private String title; private String description; @ManyToOne @JsonIgnore private Category parent; @Override public long getId() { return id; } @Override public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Category getParent() { return null;//return parent; } public void setParent(Category parent) { // this.parent = parent; } public boolean isMainCategory() { return true;// return this.parent == null; } /** * Returns the chain of parent categories with the main category on index 0 * @return Chain of categories */ public List getParentChain() { List cats = new ArrayList(); Category current = this; while(!current.isMainCategory()) { cats.add(current); current = current.getParent(); } cats.add(current); Collections.reverse(cats); return cats; } @Override public String toString() { return this.title; } @Override public boolean equals(Object o) { if(!(o instanceof Category))return false; Category c = (Category)o; return c.title.equals(this.title); } @Override public int hashCode() { return super.hashCode(); } } 

rest控制器function

 @RequestMapping(value="/{id}", method=RequestMethod.GET) public ResponseEntity get(@PathVariable("id") long categoryId) { Category c = service.getCategoryRepository().ReadValue(categoryId); if(c == null) return new ResponseEntity(HttpStatus.NOT_FOUND); return new ResponseEntity(c,HttpStatus.OK); } 

注意

即使我替换return new ResponseEntity(c,HttpStatus.OK); return new ResponseEntity(new Category(),HttpStatus.OK); 我将得到一个stackoverflow whilist没有字段包含值。

它适用于我的其他类,它只是这个类导致stackoverflow。

如果您评论private Category parent; 你不会有StackOverflow。 我在具有循环依赖项的项目中遇到了同样的问题。

解决此问题的最佳方法是使用父级的id而不是类,如:

 private Long parentId; 

编辑:

问题在于尝试序列化的getParentChain() 。 通过在方法之前添加@JsonIgnore来解决问题。

当然, @JsonIgnore完成了这项工作。 但是如果我们在JSON输出中需要忽略字段呢?

解决方案非常简单。

我们通过@JsonManagedReference注释在我们关系的一侧注释我们的’有罪’字段(这意味着我们的@ManyToMany注释)。

@JsonBackReference在关系的另一边(其中放置了@OneToMany )。

就是这样。 没有更多的递归循环。

一个注释可以解决您的问题。

在课堂上添加以下注释。

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

另一种方法是在Collections @JsonManagedReference上为正向和@JsonBackReference注释。 用于映射中的反向。

例:

 public class User{ @JsonManagedReference @OneToMany(mappedBy = "user") Set
s = new Hashset<>(); } public class Address{ @JsonBackReference @ManyToOne @JoinColumn User user; }