Hibernate 使用@OneToMany 和@ManyToOne 上传数据,但外键仍然为 Null

Hibernate uploads data with @OneToMany and @ManyToOne but the foreign key remains Null

模块代码:

@Data
@NoArgsConstructor
@ToString
@Entity(name = "modules")
@Table(name = "modules")
public class Module {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "module_id")
    private int moduleId;

    @Column(name = "module_name")
    private String moduleName;

    @Column(name = "module_code")
    private String moduleCode;

    @Column(name = "moderator_lecturer")
    private String moderatorLecturerId;

    @Column(name = "secondary_lecturer")
    private String secondaryLecturerId;

    @OneToMany(mappedBy = "foreignModuleId", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Assessment> assessments;

    public void addAssessment(Assessment assessment) {
        assessments.add(assessment);
    }
}

作业代码

@Data
@NoArgsConstructor
@ToString
@Entity(name = "assessments")
@Table(name = "assessments")
public class Assessment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "assessment_id")
    private int assessmentId;

    @Enumerated(EnumType.STRING)
    @Column(name = "assessment_type")
    private AssessmentType assessmentType;

    @Column(name = "assessment_weight")
    private int assessmentWeight;

    @Column(name = "assessment_weeks")
    private String weeks;

    @Column(name = "assessment_upload_date")
    private LocalDate uploadDate;

    @Column(name = "assessment_deadline_date")
    private LocalDate deadlineDate;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "assessment_belongsTo_module", referencedColumnName = "module_id")
    private Module foreignModuleId;
}

一个模块可以有很多评估,因此我选择了这些注释。 我首先从 excel 文件中提取这些数据并将它们组合在一个列表中(稍后作为称为“模块”的参数传递)。该列表的形式为: Module(moduleId=0, moduleName=Programming Principles and Algorithms, moduleCode= CCS1110, moderatorLecturerId=Dr Stamatopoulou, secondaryLecturerId= Dr Efremidis, assessments=[评估(assessmentId=0, assessmentType=ASSESSED_LAB, assessmentWeight=35, weeks= 00001000000000000,uploadDate=null,deadlineDate=null,foreignModuleId=null),评估(assessmentId=0,assessmentType=ASSESSED_LAB,assessmentWeight=65,weeks=0000000000000001,uploadDate=null,deadlineDate=null,foreignModuleId=null)] ) 模块(moduleId=0,moduleName=编程方法和设计,moduleCode=CCS1115,moderatorLecturerId=Dr Stamatopoulou,secondaryLecturerId=Dr Efremidis,assessments=[Assessment(assessmentId=0,assessmentType=PROJECT,assessmentWeight=35,weeks=00000000000000100,uploadDate=空,deadlineDate=null,foreignModuleId=null),评估(assessmentId=0,assessmentType=ASSESSED_LAB,assessmentWeight=65,weeks=00000000000000001,uploadDate=null,deadlineDate=null,foreignModuleId=null)])

然后我将列表上传到数据库:

@NoArgsConstructor
@Data
public class AppDAOImpl implements AppDAO{

    private SessionFactory factory;

    public void upload(List<com.project.model.Module> modules) {
        Session currentSession = factory.getCurrentSession();
        try {
            currentSession.beginTransaction();
            for(Module module : modules) { 
                currentSession.save(module);
            }
            currentSession.getTransaction().commit();
        }
        finally {
            currentSession.close();
            factory.close();
        }
    
    }
}

当我执行 Hibernate 时创建表单查询: 休眠:插入模块(moderator_lecturer、module_code、module_name、secondary_lecturer)值(?、?、?、?) Hibernate:插入评估(assessment_type、assessment_weight、assessment_deadline_date、assessment_belongsTo_module、assessment_upload_date、assessment_weeks)值(?、?、?、 ?,?,?) Hibernate:插入评估(assessment_type、assessment_weight、assessment_deadline_date、assessment_belongsTo_module、assessment_upload_date、assessment_weeks)值(?、?、?、 ?,?,?)

但是在数据库中 table 的评估,字段 assessment_belongsTo_module 为空。

我的数据库有这种形式:

我试了很多方法都无法解决问题。我也读过类似的帖子,但仍然一无所获。也许我在数据库中的每个 table 上创建字段的方式有问题(例如外键)?

  1. 不要为 class 使用名称 Module,比如 MModule。它与 java.lang.Module.
  2. 相混淆
  3. 创建 JpaRepository MModuleRepository。然后在控制器中,简单地写一些像
    for(MModule module :modules){
       moduleRepository.save(module);
    }

导致此问题的原因是我没有在评估 class 中初始化属性“foreignModuleId”。所以当我在某个时候从我的 excel 中提取数据时,我有以下几行:

assessment.setForeignModuleId(module); // I add the module in which the assessment belongs.
module.addAssessment(assessment); // I then add that assessment to the @OneToMany assessments List

我还通过将其包含在 Assessment class:

@ToString.Exclude 
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assessment_belongsTo_module", referencedColumnName = "module_id")
private Module foreignModuleId = new Module();

这非常重要,因为 Lombok 的 toString 会导致递归调用,然后导致前面提到的异常。