Ajax gets only the first object from a list got from the controller

时间:2018-01-28 09:29:03

标签: ajax spring hibernate spring-mvc

I just started working with Java for web and I have this basic Quizz project where I integrated ajax.

In spring I have a controller which returns a list of answer objects based on a question id.

@RequestMapping(value = "/view-answers/{id}", method = RequestMethod.GET, produces = "application/json")
@SuppressWarnings("unchecked")
public @ResponseBody List<Answer> viewAnswers(@PathVariable int id, Model model){
    // TODO: Get all quizzes
    List<Answer> answers = answerService.findByQuestionId(id);

    return answers;
}

Using this ajax fuction I retrieve the data from the controller with only one problem: It gets only the first object in full and the rest of the objects are just ID`s of the objects.

// DO GET
function ajaxGet(){
    var questionID = $(".questionID").val();
    $.ajax({
        type : "GET",
        url : "/view-answers/"+questionID,
        dataType: 'json',
        headers: {
            Accept: 'application/json'
        },
        success: function(answers){

            $('#answersList .answersUl').empty();
            var ansList = "";
            console.log(answers);
            $.each(answers, function(i, answer){
                var answer = i + "." + answer.answer + "<br />";
                $('#answersList .answersUl ').append(answer);
            });
            console.log("Success: ", answers);
        },
        error : function(e) {
            $("#getResultDiv").html("<strong>Error! Something went wrong.</strong>");
            console.log("ERROR: ", e);
        }
    });
}

It can be a problem with my controller function? The findByQuestionId function is this:

@Override
public List<Answer> findByQuestionId(int question_id) {
    Session session = sessionFactory.openSession();
    session.beginTransaction();
    Question question = session.find(Question.class, question_id);
    List<Answer> answers = question.getAnswers();
    session.getTransaction().commit();
    //Close the session
    session.close();
    return answers;
}

This is what I'm getting with ajax right now:

enter image description here

内的文字

我的实体的重要部分:

QUIZZ:

@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "quizz_id")
public class Quizz {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int quizz_id;
    private String title;
    private String description;
    private int nr_participanti;
    private int timp_disp;
    private int nr_intrebari;
    @OneToMany(mappedBy = "quizz", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Question> questions;

问题:

@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id")
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String titlu;
    @ManyToOne
    private Quizz quizz;
    @OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Answer> answers;

答案:

@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "answer_id")
public class Answer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int answer_id;
    private String answer;
    private boolean corect;
    @ManyToOne
    private Question question;

2 个答案:

答案 0 :(得分:0)

我认为这是延迟加载服务bean中相关Answer对象的问题。由于您似乎使用了Hibernate,question.getAnswers()返回的答案列表可能不会急切地获取与该问题相关的所有答案。 Hibernate默认情况下会懒惰地加载一对多关系。您在服务方法findByQuestionId结束时关闭Hibernate会话,因此在生成控制器的响应时,只要迭代列表就无法加载剩余的答案。

您可以在服务中尝试以下操作:

List<Answer> answers = question.getAnswers();
List<Answer> loadedAnswers = answers.stream().collect(Collectors.toList());

这将立即迭代为问题关系返回的答案列表,并将所有答案添加到另一个临时列表中。然后可以安全地关闭Hibernate会话。

答案 1 :(得分:0)

对于遇到相同问题或以某种方式发现此问题的任何人。问题确实存在于我的实体中。 对于每个实体,我必须添加两个注释:

@JsonManagedReference是引用的前向部分 - 正常序列化的部分。 @JsonBackReference是引用的后半部分 - 它将从序列化中省略。

因此,我使用@JsonManagedReference注释ManyToOne对象,OneToMany使用@JsonBackReference列出对象。这是唯一缺少的部分,以使其发挥作用。