0

I have three entities. I want to save a survey. The survey will contain all the data that is neccessary:id,section, questions. The survey_section_question table is created successfully and when I want to retrieve existing data I receive the desired object. I have a problem when I want to save a survey that has sections and questions.I receive the following error:

java.sql.SQLException: Field 'survey_id' doesn't have a default value

Does anyone see what is the error there? I attach the code for the three entities.Thanks in advance for the help!

    @Entity
    @Table(name="Surveys")
    @Data
    public class Survey {
        @Id
        @Column(name = "id")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        private String description;
        private String createdBy;
    
        @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
        @JoinTable(
                name = "survey_section_question",
                joinColumns = @JoinColumn(name = "survey_id"),
                inverseJoinColumns = @JoinColumn(name = "section_id")
        )
        private List<SurveySection> sections;
    }

    @Entity
    @Table(name="SurveySections")
    @Data
    public class SurveySection {
        @Id
        @Column(name = "id")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        private String description;
    
        @ManyToMany
        @JoinTable(
                name = "survey_section_question",
                joinColumns = @JoinColumn(name = "section_id"),
                inverseJoinColumns = @JoinColumn(name = "question_id")
        )
        private List<SurveyQuestion> questions;
    }

@Entity
@Table(name="SurveyQuestions")
@Data
public class SurveyQuestion {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String description;
    private String createdBy;
    private boolean textAnswer;
    private boolean gradeAnswer;
}

The sended json:

{"id":1,"name":"mu","description":"sss","createdBy":"xx","sections":[{"id":5,"name":"s2","description":"","questions":[{"id":15,"name":"adawd","description":"awdawd","createdBy":"","textAnswer":true,"gradeAnswer":true}],"selectedQuestion":"15"}]}

The code used for update:

@PutMapping("/{id}")
Survey update(@RequestBody Survey surveyData, @PathVariable Long id) {
    return surveyService.findById(id)
            .map(survey -> {
                survey.setName(surveyData.getName());
              survey.setDescription(surveyData.getDescription());
                survey.setSections(surveyData.getSections());
                survey.setCreatedBy("Test");
                return surveyService.save(survey);
            })
            .orElseGet(() -> surveyService.save(surveyData));
}

The save for the survey service it is just a default call to jpa repository which calls save.

2
  • Please show us your code that adds a survey. Also, @ManyToMany associations should be modeled with a Set and not a List. A set will give you much better performance. Commented Jul 7 at 13:59
  • @LeeGreiner I added the code
    – onner
    Commented Jul 7 at 14:38

1 Answer 1

0

The fetch type is only used for queries. Your save repository method will simply call EntityManager.persist() or EntityManager.merge(). Merge will only merge the survey entity, not the children. You will need to manage the children manually in your surveyService.save() method.

2
  • Can you show me an example, please? I set on the survey object the sections and for the section object the questions. Still the same result :/
    – onner
    Commented Jul 7 at 16:54
  • You have modeled many-to-many on the child collections which means a survey section can belong to multiple surveys. Similarly, a survey question can belong to more than one survey section. If this is not the case, then you should be using orphanRemoval = true. Also, you probably want to set the cascade on the collections to persist and merge. I typically only model the many-to-one association and use queries to obtain a patent's children. Take a look at this. It's a bidirectional many-to-many. Commented Jul 7 at 18:27

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