You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring JPA保存Survey时报错:Field 'survey_id'无默认值

问题:保存/更新Survey时触发Field 'survey_id'无默认值错误

保存或更新包含sections和questions的Survey数据时,出现如下错误:

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

关联表survey_section_question已成功创建,查询现有数据可返回预期对象,但保存/更新操作失败。以下是相关代码:

实体代码

Survey类

@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;
}

SurveySection类

@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;
}

SurveyQuestion类

@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;
}

请求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"}]}

更新接口代码

@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));
}

SurveyService的save方法仅调用JPA Repository的默认save方法。


错误原因

核心问题是误用同一张关联表survey_section_question维护两组多对多关系:

  • Survey与SurveySection的多对多关联
  • SurveySection与SurveyQuestion的多对多关联

一张关联表只能对应一组多对多关系,当JPA尝试插入Survey与Section的关联数据时,这张表还需要存储Section与Question的关联字段,导致survey_id字段无法被正确赋值(或表结构本身不兼容),最终触发无默认值的错误。

解决方案

1. 拆分关联表

创建两张独立的关联表:

  • survey_section:维护Survey与SurveySection的关联,字段为survey_id、section_id
  • section_question:维护SurveySection与SurveyQuestion的关联,字段为section_id、question_id

2. 修改实体注解

更新Survey类的多对多关联配置:

@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(
        name = "survey_section",
        joinColumns = @JoinColumn(name = "survey_id"),
        inverseJoinColumns = @JoinColumn(name = "section_id")
)
private List<SurveySection> sections;

更新SurveySection类的多对多关联配置:

@ManyToMany
@JoinTable(
        name = "section_question",
        joinColumns = @JoinColumn(name = "section_id"),
        inverseJoinColumns = @JoinColumn(name = "question_id")
)
private List<SurveyQuestion> questions;

3. 数据库调整

删除原有的survey_section_question表,创建上述两张新关联表。

4. 优化更新逻辑(可选)

更新时传入的sections和questions是游离状态的实体,建议先加载持久化状态的对象再关联,避免额外问题:

survey.setSections(surveyData.getSections().stream()
        .map(section -> sectionRepository.findById(section.getId()).orElseThrow(() -> new RuntimeException("Section not found")))
        .collect(Collectors.toList()));

内容的提问来源于stack exchange,提问作者onner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:13:22