【问题标题】:Hibernate uploads data with @OneToMany and @ManyToOne but the foreign key remains NullHibernate 使用 @OneToMany 和 @ManyToOne 上传数据,但外键仍然为 Null
【发布时间】:2022-01-03 07:56:58
【问题描述】:

模块代码:

@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=编程原理和算法, moduleCode= CCS1110, moderatorLecturerId=Dr Stamatopoulou, secondaryLecturerId= Dr Efremidis,assessment=[Assessment(assessmentId=0,assessmentType=ASSESSED_LAB,assessmentWeight=35, week=00001000000000000,uploadDate= null,deadlineDate=null,foreignModuleId=null),Assessment(assessmentId=0,assessmentType=ASSESSED_LAB,assessmentWeight=65,week=000000000000000001,uploadDate=null,deadlineDate=null,foreignModuleId=null)]) Module(moduleId=0, moduleName=Programming Methodology and Design, moduleCode= CCS1115, moderatorLecturerId=Dr Stamatopoulou, secondaryLecturerId= Dr Efremidis,assessment=[Assessment(assessmentId=0,assessmentType=PROJECT,assessmentWeight=35,weeks=00000000000000100,uploadDate= null,deadlineDate=null,foreignModuleId=null),Assessment(assessmentId=0,assessmentType=ASSESSED_LAB,assessmentWeight=65,week=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 创建表单查询时: Hibernate:插入模块(moderator_lecturer,module_code,module_name,secondary_lecturer)值(?,?,?,?) 休眠:插入评估(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)值(?、?、?、?、?、?)

但在 Assessments 表的数据库中,assessment_belongsTo_module 字段为空。

我的数据库有这种形式:

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

【问题讨论】:

  • 能否展示初始化模块和评估的代码?
  • 模块和评估是从 excel 文件中提取的。这是一个复杂的过程(我有一天会重构它)。我不知道你为什么想看到那个。认为最终结果由上述形式的对象组成(在评估代码之后)。
  • 在持久化之前确保对模块的引用在评估中初始化

标签: java mysql spring hibernate


【解决方案1】:
  1. 不要将名称模块用于类,例如 MModule。它与 java.lang.Module 混淆了。
  2. 创建 JpaRepository MModuleRepository。然后在控制器中,简单地编写类似
    for(MModule module :modules){
       moduleRepository.save(module);
    }

【讨论】:

    【解决方案2】:

    造成这种情况的问题与我没有在评估类中初始化属性“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 类中,修复了每当我执行从数据库中检索这些数据等操作时导致的 stackOverFlow 异常:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      相关资源
      最近更新 更多