父母在任何情况下都不要懒惰地装载孩子

时间:2018-12-06 11:21:14

标签: java json hibernate spring-data-jpa

我正在开发REST API,并且我有一个Question父级和Answer(以及与这两个关联的User)子级。我要实现的是,使用questionService.getAllQuestions()仅从数据库中加载问题和用户。当我打电话给questionService.getQuestion(id)时,我希望从数据库中加载该问题以及所有答案以及该问题所包含的用户(回答的用户)。通过Spring-boot自动将所有数据转换为JSON对象

但是在我目前的情况下,即使使用getAllQuestions(),也会从数据库加载所有数据。对于问题概述请求没有意义,但对于问题详细信息请求是必需的。

问题父实体:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Set;

@Entity
@Table(name = "vragen")
public class Question extends BaseEntity {
    @Column(name = "vraag")
    private String question;

    @Column(name = "bericht")
    private String message;

    @ManyToOne
    @JoinColumn(name = "gebruiker")
    private Gebruiker gebruiker;

    @Column(name = "beantwoord", insertable = false)
    private boolean answered;

    @Column(name = "gepost_op", insertable = false)
    private Timestamp postedOn;

    @Column(name = "actief", insertable = false)
    @JsonIgnore
    private boolean active;

    @OneToMany(mappedBy = "question")
    @JsonManagedReference
    private Set<Answer> answers;


    public Question() {}

    public Question(String question, String message, Gebruiker gebruiker) {
        this.question = question;
        this.message = message;
        this.gebruiker = gebruiker;
    }

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Gebruiker getGebruiker() {
        return gebruiker;
    }

    public void setGebruiker(Gebruiker gebruiker) {
        this.gebruiker = gebruiker;
    }

    public boolean isAnswered() {
        return answered;
    }

    public void setAnswered(boolean answered) {
        this.answered = answered;
    }

    public Timestamp getPostedOn() {
        return postedOn;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public Set<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(Set<Answer> answers) {
        this.answers = answers;
    }
}

答案实体:

import com.fasterxml.jackson.annotation.JsonBackReference;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.sql.Timestamp;

@Entity
@Table(name = "antwoorden")
public class Answer extends BaseEntity {
    @Size(min = 10)
    @Column(name = "bericht")
    private String message;

    @ManyToOne
    @JoinColumn(name = "gebruiker")
    private Gebruiker gebruiker;

    @ManyToOne
    @JoinColumn(name = "vraag")
    @JsonBackReference
    private Question question;

    @Column(name = "gepost_op", insertable = false)
    private Timestamp postedOn;

    @Column(name = "actief", insertable = false)
    private boolean active;


    public Answer() {}

    public Answer(String message, Gebruiker gebruiker, Question question) {

    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Gebruiker getGebruiker() {
        return gebruiker;
    }

    public void setGebruiker(Gebruiker gebruiker) {
        this.gebruiker = gebruiker;
    }

    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
    }

    public Timestamp getPostedOn() {
        return postedOn;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}

@OneToMany应该默认默认延迟加载答案,即使我明确设置了该选项也不会发生。

是否可以使用JPA实现此目的,还是需要在自定义实现中手动编写查询?

1 个答案:

答案 0 :(得分:1)

我注意到是由杰克逊(Jackson)引起的,尤其是@JsonManagedReference。删除它并添加@JsonBackReference可以使其正确地延迟加载,尽管此处实际上并没有该注释。

有关实际解决方案,请参见Configure Jackson to omit lazy-loading attributes in Spring Boot