Springboot - 未返回子实体的对象列表

Springboot - list of objects with child entities not returned

我有一个名为 SubmittedQuiz 的对象,它由一个 Quiz 对象、User 对象和 submittedQuestions 对象组成。

当我尝试执行此请求时:

GET http://localhost:8080/SubmittedQuiz/getForUser/10

我收到 return 了以下错误:

Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->edowl.Model.SubmittedQuiz["user"]->edowl.Model.User$HibernateProxy$lNsgwyQb["hibernateLazyInitializer"])"

请求发现对象很好,当设置断点时它实际上得到了对象列表但是它在 return 语句上失败了。

控制器方法如下图:

@GetMapping("/getForUser/{id}")
public ResponseEntity<List<SubmittedQuiz>> getSubmittedQuizForUser(@PathVariable("id") Long id){
    List<SubmittedQuiz> quizzes = submittedQuizService.findAllByUserId(id);
    return new ResponseEntity<>(quizzes, HttpStatus.OK); //ok is 200 status code
}

服务如下所示:

public List<SubmittedQuiz> findAllByUserId(Long id) {
   return submittedQuizRepo.findAllByUserId(id);
}

Repo如下所示:

List<SubmittedQuiz> findAllByUserId(Long id);

SubmittedQuiz如下图:

@Entity 
@Table(name = "Submitted_Quiz")
public class SubmittedQuiz {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinTable(name = "User_Quiz_Submitted",
            joinColumns = { @JoinColumn(name = "quiz_submitted_id")},
            inverseJoinColumns = { @JoinColumn(name = "user_id")})
    public User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinTable(name = "Quiz_Quiz_Submitted",
            joinColumns = { @JoinColumn(name = "quiz_submitted_id")},
            inverseJoinColumns = { @JoinColumn(name = "quiz_id")})
    public Quiz quiz;

    private float score;
    private LocalDate generatedDate;
    private float timeTaken;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "quiz_submitted_question",
            joinColumns = { @JoinColumn(name = "quiz_submitted_id")},
            inverseJoinColumns = { @JoinColumn(name = "question_id")})
    @Column(name = "submitted_questions")
    private Set<SubmittedQuestion> submittedQuestions = new HashSet<>();

我看到了一项关于在对象上添加 @JsonBackReference@JsonManagedReference 注释的建议。
但是,到目前为止,我不需要对任何其他对象执行此操作,并且我使用的当前注释在这一点之前就足够了

有什么建议吗?

您可以尝试使用 EntityGraph 来达到这个目的。

并设置为 atributePaths 所有具有 FetchType.LAZY 的实体:

@EntityGraph(attributePaths = {"user", "quiz", "submitted_questions"})
List<SubmittedQuiz> findAllByUserId(Long id);

控制器的一些提示 - 您不需要直接设置 200 响应。默认返回状态码OK。所以以下就可以了:

@GetMapping("/getForUser/{id}")
public List<SubmittedQuiz> getSubmittedQuizForUser(@PathVariable("id") Long id){
    return submittedQuizService.findAllByUserId(id);
}

更新:

尝试添加网页配置如::

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Bean
    public Module datatypeHibernateModule() {
        return new Hibernate5Module();
    }
}

如果无法解决错误问题,请尝试添加:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

你所有的子实体:

@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(...)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public User user;

此外,JPA API 要求您的实体必须是可序列化的。 您必须按如下方式更新它:

public class SubmittedQuiz implements Serializable {
    private static final long serialVersionUID = 1L;

也为其他实体添加相同的内容(用户测验...)