0

I am a new self taught programmer, I am making my first independent project and running into some problems. I am making a quiz app, and I want create a class for a quiz, and another class for questions that are mapped to each quiz. I created what I think should be the appropriate models, views, and controllers, but in mysql, there is nothing mapping the questions and quiz together. I did a similar-ish tutorial and it seems like hibernate connects the data, but it is not happening this time.

I have tried to rewrite my processCreateNewQuiz method in QuizCreateController, and so far have had no success. Any ideas on what I should look into to move forward?

Below is what I think is the relevant code:

Quiz class

package org.launchcode.trivia.models;

import javax.persistence.Entity;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Quiz extends AbstractEntity {

    public String name;

    @OneToMany (mappedBy = "quiz")
    private List<QuestionAnswerInfo> questions = new ArrayList<>();

    public Quiz(){}

    public Quiz(String name, ArrayList<QuestionAnswerInfo> questions) {
        super();
        this.name = name;
        this.questions = questions;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<QuestionAnswerInfo> getQuestions() {
        return questions;
    }

    public void setQuestions(List<QuestionAnswerInfo> questions) {
        this.questions = questions;
    }

    public void addQuestions(List<QuestionAnswerInfo> questions, QuestionAnswerInfo question) {
        questions.add(question);
    }
}

QuestionAnswerInfo class

package org.launchcode.trivia.models;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;

@Entity
public class QuestionAnswerInfo extends AbstractEntity{

    private String question;
    private String answer;
    private String questionType;
    private String additionalAnswerInfo;

    @ManyToOne
    private Quiz quiz;


    public QuestionAnswerInfo (){}

    public QuestionAnswerInfo(String question, String answer, String questionType, String additionalAnswerInfo,
                              Quiz quiz) {
        super();
        this.question = question;
        this.answer = answer;
        this.questionType = questionType;
        this.additionalAnswerInfo = additionalAnswerInfo;
        this.quiz = quiz;
    }

    public String getQuestion() {
        return question;
    }

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

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    public String getQuestionType() {
        return questionType;
    }

    public void setQuestionType(String questionType) {
        this.questionType = questionType;
    }

    public String getAdditionalAnswerInfo() {
        return additionalAnswerInfo;
    }

    public void setAdditionalAnswerInfo(String additionalAnswerInfo) {
        this.additionalAnswerInfo = additionalAnswerInfo;
    }
}

QuizCreateController

package org.launchcode.trivia.controllers;

import org.launchcode.trivia.models.QuestionAnswerInfo;
import org.launchcode.trivia.models.Quiz;
import org.launchcode.trivia.models.data.QuestionRepository;
import org.launchcode.trivia.models.data.QuizRepository;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;


@Controller
public class QuizCreateController {

    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private QuizRepository quizRepository;

    @RequestMapping("create")
    public String displayCreateNewQuiz(Model model) {
        model.addAttribute(new Quiz());
        model.addAttribute("questions", new QuestionAnswerInfo());
        return "create";
    }

    @PostMapping("create")
    public String processCreateNewQuiz(@ModelAttribute Quiz newQuiz, @ModelAttribute QuestionAnswerInfo questions,
                                       Model model) {
        List<QuestionAnswerInfo> quizQuestions = new ArrayList<>();
        quizQuestions.add(questions);
        newQuiz.setQuestions(quizQuestions);
        quizRepository.save(newQuiz);
        questionRepository.save(questions);

        return "index";
    }
}

create.html View

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<h1>Create a Quiz</h1>

<form method="post">
    <div>
        <label th:for="name">Quiz Name</label>
        <input th:field="${quiz.name}"/>
    </div>
    <br>
    <div>
        <label th:for="question">Add a Question</label>
        <input th:field="${questions.question}"/>
    </div>
    <div>
        <label th:for="answer">Add an Answer</label>
        <input th:field="${questions.answer}"/>
    </div>
    <div>
        <label th:for="questionType">Question Type</label>
        <input th:field="${questions.questionType}"/>
    </div>
    <div>
        <label th:for="additionalAnswerInfo">Add Additional Information</label>
        <input th:field="${questions.additionalAnswerInfo}"/>
    </div>



    <input type="submit" value="Create Quiz"/>
</form>

</body>
</html>

Let me know if you need more info to help me. I am still learning how to even ask for help!

Thanks!

3
  • What is the error you are getting? Commented Apr 26, 2021 at 16:39
  • There is no error. However, when I add a quiz, both the quiz and the question get added to the database, but there is no relation between them. My quiz table has the id and name field filled. My question_answer_info table has id, question, answer, question_type, and additional_answer_info all correctly filled in, but (hibernate generated?) quiz_id field, which should be the foreign key, is null. I want it to correspond to the quiz that was just added.
    – Sam Berger
    Commented Apr 26, 2021 at 20:46
  • You need to associate the classes with each other. See vladmihalcea.com/… for more details on how to correctly implement bidirectional one-to-many. Commented Apr 27, 2021 at 6:25

1 Answer 1

0

I made this work, at least unidirectionally. I am not sure I needed bidirectional. I needed to change the annotations in @OneToMany in Quiz, and changed the controller method.

Quiz Model code to note:

    @OneToMany (cascade = CascadeType.ALL)
    @JoinColumn(name = "quiz_question_foreign_id", referencedColumnName = "id")
    private List<QuestionAnswerInfo> questions = new ArrayList<>();

Controller

@PostMapping("create")
    public String processCreateNewQuiz(@ModelAttribute Quiz newQuiz, @ModelAttribute QuestionAnswerInfo questions,
                                       Model model) {
        newQuiz.getQuestions().add(questions);
        quizRepository.save(newQuiz);
        return "index";
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.