Spring JPA从JpaRepository返回无限递归



我有一个类似的控制器类


@Controller
public class ExerciseController {
private static final Logger logger = LogManager.getLogger(ExerciseController.class);
private final ExerciseRepository exerciseRepository;
@Autowired
public ExerciseController(ExerciseRepository exerciseRepository) {
this.exerciseRepository = exerciseRepository;
}

@PostMapping("/exercises")
public ResponseEntity<Exercise> createExercise(@RequestBody Exercise exercise) {
Exercise savedExercise = exerciseRepository.save(exercise);
return new ResponseEntity<Exercise>(savedExercise,HttpStatus.CREATED);
}
@RequestMapping("/exercises/{id}")
public ResponseEntity<Exercise> getExerciseById(@PathVariable int id) {
Exercise exercise = exerciseRepository.getOne(id);
return new ResponseEntity<Exercise>(exercise, HttpStatus.OK);
}
}

链接到此控制器的存储库是一个类似的简单JpaRepository

package com.company.app.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.company.app.model.Exercise;
@Repository
public interface ExerciseRepository extends JpaRepository<Exercise, Integer> {
Exercise findById(int id);
}

当我试图达到与/exercises/{id}相关联的端点时,我得到了无限递归。Exercise模型是这样设置的

package com.company.app.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Table(name="exercise")
@Data
public class Exercise {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@MapsId("chapterId")
@JoinColumns({
@JoinColumn(name="chapterId", referencedColumnName="id"),
})
@ManyToOne
private Chapter chapter;
private String exercise;
private String answer;
private String question;
private String a;

private String b;
private String c;
}

我想知道为什么这会返回无限递归?我收到的错误是

2021-04-02 19:30:28.120 ERROR 110200 --- [nio-8080-exec-6] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/exercises/1] and exception [Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.company.app.model.Account["user"]->

章节实施

package com.company.app.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Table(name="chapter")
@Data
public class Chapter {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

private String title;

@MapsId("bookId")
@JoinColumns({
@JoinColumn(name="bookId", referencedColumnName="id"),
})
@ManyToOne
private Book book;
}

之所以会发生这种情况,是因为默认情况下,@Data注释会为所有字段创建equals/hashCode/toString实现,因此在这些方法中,ExerciseChapter之间有一个无限循环。

我建议您通过在chapterexercise字段上添加@EqualsAndHashCode.Exclude@ToString.Exclude来排除这些字段。

最新更新