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:
内的文字我的实体的重要部分:
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;
答案 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列出对象。这是唯一缺少的部分,以使其发挥作用。