avoid hibernate lazy initialization exception

2020-06-20 12:57发布

问题:

I have two classes called Lecturer and Course. My Lecturer class has a List of Course objects a variable as shown

@OneToMany(mappedBy = "lecturer")
@NotFound(action = NotFoundAction.IGNORE)
private List<Course> courseList = new ArrayList<Course>();

In my course class I have a Lecturer object as a variable as below.

@ManyToOne
@JoinTable(name = "course_lecturer", joinColumns = @JoinColumn(name = "course_id"), inverseJoinColumns = @JoinColumn(name = "lecturer_id"))
private Lecturer lecturer;

Now I have a spring Controller method that returns a json object of Lecturer as below.

@RequestMapping(value = "/getlecturerbyid", method = RequestMethod.POST)
public @ResponseBody
Object getLecturer(@ModelAttribute(value = "id") Lecturer lecturer) {
    Map<String, Object> response = new HashMap<String, Object>();
    response.put("message", "succeess");
    response.put("lecturer", lecturer);
    return response;
}

The problem is it throws a lazy initialization exception. Therefore I set fetch type in both variables in Lecturer and Course class to eager. Now the problem is it infinitely tries to fetch objects eagerly(if I unset fetch of either, it raises the same exception).

On the other hand if I remove the variable of either class, then the hibernate does not know that there is a relationship for another. eg: if I remove course list from Lecturer and delete one of the Lecturer objects then hibernate does not remove the course objects that are related with the deleted Lecturer object. so i have to write a hibernate query and remove it manually in the code.

Can you please suggest me on how to over come this issue?

回答1:

This is happening because of circular reference(parent -> child ->parent). I am sure you have got the idea.

The simplest solution for your problem is to iterate the list of courses and set the Lecturer as null before putting it into response to break the circular relationship as below:

   Object getLecturer(@ModelAttribute(value = "id") Lecturer lecturer) {
       Map<String, Object> response = new HashMap<String, Object>();
       response.put("message", "succeess");

       //break the circular relationship
       if(lecturer.getCourses() != null){
          for(Course course: lecturer.getCourses()){
               course.setLecturer(null);
          }
       }
       response.put("lecturer", lecturer);
       return response;
   }


回答2:

This problem can be overcome by using @JsonIgnore annotation if you are using jackson mapper. This link addresses the issue for jackson.