4

I have two JPA Entity classes, Task and TaskList. There's a one-to-many relationship between TaskList and Task (obviously) with the tasklist_id foreign key in the task table.

The Task class is this:

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

and the TaskList class is this:

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

    // Id and two fields

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

    // Constructor
    public TaskList() {}
}

When I try to add an automatic getter and setter to these two classes and a toString() function, I get a StackOverflowError.

How do I go about writing getters and setters for the two fields so that I get a proper object with toString()?

cst1992
  • 3,823
  • 1
  • 29
  • 40
  • Pretty like it is not a JPA/Hibernate. Read this [question](http://stackoverflow.com/questions/3593893/why-im-getting-stackoverflowerror), maybe it can be relevant to you. – Bonifacio Feb 05 '16 at 13:11

2 Answers2

4

To future readers, the solution is to use back references:

Task class:

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

TaskList class

@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() {}
}
  • Add the proper annotations. Add ManagedReference to @OneToMany(parent) and BackReference to @ManyToOne(child). Write table names in the brackets as indicated, separated by a hyphen.

This takes care of the infinite recursion automatically, solving the StackOverflowError problem.

Some links:

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

cst1992
  • 3,823
  • 1
  • 29
  • 40
  • Your answer isn't corresponding your question. Your question was about `toString()` implementation, not about conversion objects net to JSON. :) – v.ladynev Feb 08 '16 at 14:18
  • This solution solves the fundamental problem - infinite recursion - that results from using toString() directly. Jackson is used there, as shown in the error log, so these annotations are relevant. Also, I've tested this in my own code personally. :) – cst1992 Feb 08 '16 at 14:20
  • There are not an error log, jackson or json tags in your question. :) – v.ladynev Feb 08 '16 at 14:22
  • @v.ladynev Also, I have tried other ways, and none worked the way this did. Not to mention they were making writing some of other functions extremely difficult. – cst1992 Feb 08 '16 at 14:23
1

When you do tasks.toString() the default implementation of toString() in the AbstractCollection call toString() for the every element in the list (for every Task). So you should not to use a default implementation and get information from the tasks in a loop and don't call toString() for every Task of course. You can get from the Task and add to a result string task's id or name.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67