2016-02-05 70 views
1

我有两个JPA实体类,任务和TaskList。 TaskList和Task(显然)与表中的tasklist_id外键之间存在一对多关系。toString()函数为JPA一对多关系引发StackOverflowError

Task类是这样的:

@Entity(name = "task") 
public class Task implements Serializable {  

    // Id and 3 fields 

    @ManyToOne 
    @JoinColumn(name="tasklist_id") 
    private TaskList parentList; 

    // 3 more fields 

    // Constructor 
    public Task() {} 

    //Getters and Setters 
} 

TaskList类是这样的:

@Entity(name = "task_list") 
public class TaskList implements Serializable { 

    // Id and two fields 

    @OneToMany(mappedBy="parentList") 
    private List<Task> tasks; 

    // Constructor 
    public TaskList() {} 
} 

当我尝试自动getter和setter添加到这两个类和一个toString()函数,我得到一个StackOverflowError。

我该如何着手写两个字段的getter和setter,以便我得到一个合适的对象toString()

+0

漂亮的喜欢它不是一个JPA /休眠。阅读本[问题](http://stackoverflow.com/questions/3593893/why-im-getting-stackoverflowerror),也许它可能与你有关。 – Bonifacio

回答

2

为未来的读者,该解决方案是使用后向引用:

任务等级:

@Entity(name = "task") 
public class Task implements Serializable {  

    // Id and 3 fields 

    @JsonBackReference("task_list-task") 
    @ManyToOne 
    @JoinColumn(name="tasklist_id") 
    private TaskList parentList; 

    // 3 more fields 

    // Constructor 
    public Task() {} 

    //Getters and Setters 
} 

任务列表类

@Entity(name = "task_list") 
public class TaskList implements Serializable { 

    // Id and two fields 

    @JsonManagedReference("task_list-task") 
    @OneToMany(mappedBy="parentList") 
    private List<Task> tasks; 

    // Constructor 
    public TaskList() {} 
} 
  • 添加合适的注释。将ManagedReference添加到@OneToMany(父级),并将BackReference添加到@ManyToOne(子级)。按照指示在括号中书写表格名称,用连字符分隔。

这会自动处理无限递归,解决StackOverflowError问题。

一些链接:

http://keenformatics.blogspot.in/2013/08/how-to-solve-json-infinite-recursion.html
http://vard-lokkur.blogspot.in/2010/10/json-jackson-to-rescue.html

+0

你的回答并不对应你的问题。你的问题是关于'toString()'实现,而不是转换对象net到JSON。 :) –

+0

该解决方案解决了直接使用toString()导致的基本问题 - 无限递归。杰克逊在那里使用,如错误日志中所示,所以这些注释是相关的。另外,我已经在我自己的代码中亲自测试了这个。 :) – cst1992

+0

在你的问题中没有错误日志,杰克逊或json标签。 :) –

0

当你tasks.toString()toString()AbstractCollection呼叫toString()默认实现在列表(每Task)的每一个元素。所以你不应该使用默认实现并且从tasks得到循环中的信息,当然每Task不要调用toString()。您可以从Task中获取并添加到结果字符串任务的ID或名称。