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 上创建字段的方式有问题(例如外键)?
- 不要为 class 使用名称 Module,比如 MModule。它与 java.lang.Module.
相混淆
- 创建 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 会导致递归调用,然后导致前面提到的异常。
模块代码:
@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 上创建字段的方式有问题(例如外键)?
- 不要为 class 使用名称 Module,比如 MModule。它与 java.lang.Module. 相混淆
- 创建 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 会导致递归调用,然后导致前面提到的异常。