2015-08-05 4 views
4

При попытке сериализации категории я получаю stackoverflow.Исключение stackoverflow Json (quickxml)

Исключение

Внимание: StandardWrapperValve [диспетчер]: Servlet.service() для сервлета диспетчера бросил исключение java.lang.StackOverflowError на java.lang.ClassLoader.defineClass1 (нативный метод) при java.lang.ClassLoader.defineClass (ClassLoader.java:760) в org.apache.felix.framework.BundleWiringImpl $ BundleClassLoader.findClass (BundleWiringImpl.java:2279) в org.apache.felix.framework.BundleWiringImpl. findClassOrResourceByDelegation (BundleWiring Impl.java:1501) на org.apache.felix.framework.BundleWiringImpl.access $ 400 (BundleWiringImpl.java:75) в org.apache.felix.framework.BundleWiringImpl $ BundleClassLoader.loadClass (BundleWiringImpl.java:1955) на java.lang.ClassLoader.loadClass (ClassLoader.java:357) в com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields (BeanSerializerBase.java:660) на com.fasterxml.jackson. databind.ser.BeanSerializer.serialize (BeanSerializer.java:152) на com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents (IndexedListSerializer.java:100) на com.fasterxml.jackson.databind. ser.imp l.IndexedListSerializer.serializeContents (IndexedListSerializer.java:21) на com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize (AsArraySerializerBase.java:183) на com.fasterxml.jackson.databind.ser. BeanPropertyWriter.serializeAsField (BeanPropertyWriter.java:541) на com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields (BeanSerializerBase.java:644) на com.fasterxml.jackson.databind.ser.BeanSerializer. сериализации (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<Category> getParentChain() 
{ 

    List<Category> 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 Контроллер

@RequestMapping(value="/{id}", method=RequestMethod.GET) 
public ResponseEntity<Category> 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.

+0

Возможный дубликат [Весна Ожидаемая ':'? Вместо ошибки 'T' при возврате списка] (http://stackoverflow.com/questions/37848789/spring-expected-instead -of-t-error-when-returns-list) –

ответ

3

Возможно, если вы сообщите private Category parent;, у вас не будет StackOverflow. У меня такая же проблема в проекте с круговыми зависимостями.

Лучший способ для решения этой проблемы является использование идентификатора родителя вместо класса, как:

private Long parentId; 

Edit:

Проблема с getParentChain(), который пытается сериализовать. Добавив @JsonIgnore перед методом, проблема была решена.

+0

Я пробовал, но, к сожалению, это тоже не работает. Я сделал чистую сборку, чтобы убедиться, но все тот же результат – Svexo

+0

Можете ли вы указать, что такое «// и некоторые функции»? – JFPicard

+0

Я отредактировал главный пост, чтобы включить его в полный класс. – Svexo

6

Несомненно, @JsonIgnore выполняет эту работу. Но что, если нам нужно игнорировать поле в нашем выпуске JSON?

Решение очень простое.

Мы аннотируем наше «виноватое» поле @JsonManagedReference аннотации с одной стороны нашего отношения (что означает нашу аннотацию @ManyToMany).

И @JsonBackReference с другой стороны отношения (где размещен @OneToMany).

И все. Нет рекурсивных циклов.

2

В одной аннотации решается ваша проблема.

Добавить следующую аннотацию на класс.

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

Другой способ заключается в аннотации на Коллекции @JsonManagedReference для прямого направления и @JsonBackReference. для обратного направления в картографии.

пример:

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

public class Address{ 
    @JsonBackReference 
    @ManyToOne 
    @JoinColumn 
    User user; 
} 
Смежные вопросы