0

When I do

GET /survey/1

I get this response, althought there are questions and answers in my database:

{
  "surveyId": 1,
  "name": "Example",
  "questions": null,
  "answers": null
}

Why I get null in 'questions' and 'answers'? How could I fix it?

SurveyRepository:

public interface SurveyRepository extends CrudRepository<Survey, Integer> { }

Survey's model class:

@Entity
@Table(name = "survey")
public class Survey {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "surveyId")
    private Integer surveyId;

    @Column(name = "name", nullable = false)
    private String name;

    @Transient
    private List<String> questions;

    @Transient
    private List<String> answers;

    public Survey() { }

    public Survey(Integer surveyId, String name) {
        this.surveyId = surveyId;
        this.name = name;
    }

    public Integer getSurveyId() {
        return surveyId;
    }

    public String getName() {
        return name;
    }

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

    public List<String> getAnswers() {
        return answers;
    }

    public void setSurveyId(Integer surveyId) {
        this.surveyId = surveyId;
    }

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

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

    public void setAnswers(List<String> answers) {
        this.answers = answers;
    }
}

Survey's controller class:

@RestController
@RequestMapping("/survey")
public class SurveyController {

    @Autowired
    private SurveyRepository surveyRepo;

    @Autowired
    private AnswerRepository answerRepo;

    @Autowired
    private QuestionRepository questionRepo;

    @RequestMapping(method = RequestMethod.GET, value = "/{id}")
    public Survey getSurveyById(@PathVariable("id") int id) {
        return surveyRepo.findOne(id);
    }

    @RequestMapping(method = RequestMethod.POST)
    public String create(@RequestBody Survey survey) {
        surveyRepo.save(survey);
        return "Survey created";
    }

    @RequestMapping(method = RequestMethod.GET)
    public Iterable<Survey> getAllSurveys() {
        return surveyRepo.findAll();
    }

    @RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
    public String delete(@PathVariable("id") int id) {
        surveyRepo.delete(id);
        return "Survey deleted";
    }

    @RequestMapping(method = RequestMethod.PUT, value = "/{id}")
    public String update(@PathVariable("id") int id, @RequestBody Survey survey) {
        Survey update = surveyRepo.findOne(id);

        update.setName(survey.getName());
        update.setQuestions(survey.getQuestions());

        surveyRepo.save(update);
        return "Survey updated";
    }

}

Answer model class:

@Entity
@Table(name = "answer")
public class Answer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "answerId")
    private Integer answerId;

    @Column(name = "answer", nullable = false)
    private String answer;

    @ManyToOne
    @JoinColumn(name = "questionId", nullable = false)
    private Question questionId;

    public Answer() { }

    public Answer(Integer answerId, String answer, Question questionId) {
        this.answerId = answerId;
        this.answer = answer;
        this.questionId = questionId;
    }

    public Integer getAnswerId() {
        return answerId;
    }

    public String getAnswer() {
        return answer;
    }

    public Question getQuestionId() {
        return questionId;
    }

    public void setAnswerId(Integer answerId) {
        this.answerId = answerId;
    }

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

    public void setQuestionId(Question questionId) {
        this.questionId = questionId;
    }

}

Question model class

@Entity
@Table(name = "question")
public class Question {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "questionId")
    private Integer questionId;

    @Column(name = "question", nullable = false)
    private String question;

    @ManyToOne
    @JoinColumn(name = "surveyId", nullable = false)
    private Survey surveyId;

    @Transient
    private List<String> answers;

    public Question() { }

    public Question(Integer questionId, String question, Survey surveyId) {
        this.questionId = questionId;
        this.question = question;
        this.surveyId = surveyId;
    }

    public Integer getQuestionId() {
        return questionId;
    }

    public String getQuestion() {
        return question;
    }

    public Survey getSurveyId() {
        return surveyId;
    }

    public void setQuestionId(Integer questionId) {
        this.questionId = questionId;
    }

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

    public void setSurveyId(Survey surveyId) {
        this.surveyId = surveyId;
    }
}
foxbuur
  • 169
  • 1
  • 9

2 Answers2

3

You marked them as @Transient which, depending on which one you're using either means it won't be serialized, or won't be stored in the database. See this answer. Also, unrelated you should probably use @ElementCollection(targetClass = String.class) on those Lists

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109
0

You no have a relationship with your Survey and Questions.

A OneToMany relationship in Java is where the source object has an attribute that stores a collection of target objects and if those target objects had the inverse relationship back to the source object it would be a ManyToOne relationship. All relationships in Java and JPA are unidirectional, in that if a source object references a target object there is no guarantee that the target object also has a relationship to the source object. This is different than a relational database, in which relationships are defined through foreign keys and querying such that the inverse query always exists.

JPA also defines a ManyToMany relationship, which is similar to a OneToMany relationship except that the inverse relationship (if it were defined) is a ManyToMany relationship. The main difference between a OneToMany and a ManyToMany relationship in JPA is that a ManyToMany always makes use of an intermediate relational join table to store the relationship, whereas a OneToMany can either use a join table, or a foreign key in target object's table referencing the source object table's primary key. If the OneToMany uses a foreign key in the target object's table JPA requires that the relationship be bi-directional (inverse ManyToOne relationship must be defined in the target object), and the source object must use the mappedBy attribute to define the mapping.

Read More to JPA Persistence and this tutorial Spring

Gatusko
  • 2,503
  • 1
  • 17
  • 25
  • I edited my post and added Question and Answer model classes - I use @ManyToOne annotations there. – foxbuur Jan 19 '17 at 21:13