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

Time:11-26

Code for Module:

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

Code for Assignment

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

A Module can have many Assessments hence why I chose these annotations. I firstly extract those data from an excel file and combine them in a list (that is passed later on as an argument called "modules"). The list is of the form: Module(moduleId=0, moduleName=Programming Principles and Algorithms , moduleCode= CCS1110, moderatorLecturerId=Dr Stamatopoulou, secondaryLecturerId= Dr Efremidis, assessments=[Assessment(assessmentId=0, assessmentType=ASSESSED_LAB, assessmentWeight=35, weeks=00001000000000000, uploadDate=null, deadlineDate=null, foreignModuleId=null), Assessment(assessmentId=0, assessmentType=ASSESSED_LAB, assessmentWeight=65, weeks=00000000000000001, uploadDate=null, deadlineDate=null, foreignModuleId=null)]) Module(moduleId=0, moduleName=Programming Methodology and Design, moduleCode= CCS1115, moderatorLecturerId=Dr Stamatopoulou, secondaryLecturerId= Dr Efremidis, assessments=[Assessment(assessmentId=0, assessmentType=PROJECT, assessmentWeight=35, weeks=00000000000000100, uploadDate=null, deadlineDate=null, foreignModuleId=null), Assessment(assessmentId=0, assessmentType=ASSESSED_LAB, assessmentWeight=65, weeks=00000000000000001, uploadDate=null, deadlineDate=null, foreignModuleId=null)])

Then I upload the list on the database:

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

When I execute Hibernate create queries of form: Hibernate: insert into modules (moderator_lecturer, module_code, module_name, secondary_lecturer) values (?, ?, ?, ?) Hibernate: insert into assessments (assessment_type, assessment_weight, assessment_deadline_date, assessment_belongsTo_module, assessment_upload_date, assessment_weeks) values (?, ?, ?, ?, ?, ?) Hibernate: insert into assessments (assessment_type, assessment_weight, assessment_deadline_date, assessment_belongsTo_module, assessment_upload_date, assessment_weeks) values (?, ?, ?, ?, ?, ?)

But in the database on the table for Assessments, the field assessment_belongsTo_module is null.

My database has this form: enter image description here

I have tried a lot of things and cannot fix the problem. I have also read similar threads and still nothing. Maybe there is a problem in the way I have created the fields on each table in the db (e.g. the foreign key)?

CodePudding user response:

  1. Do not use the name Module for a class, say MModule. It is confused with the java.lang.Module.
  2. Create JpaRepository MModuleRepository. Then in a controller, write simply something like
    for(MModule module :modules){
       moduleRepository.save(module);
    }

CodePudding user response:

The problem that was causing this was related to the fact that I did not initialize the attribute "foreignModuleId" in the Assessment class. So when I extract the data from my excel at some point I have the lines:

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

I also fixed a stackOverFlow exception that was caused whenever I did operations like retrieving those data from the db, by including this in the Assessment class:

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

It is very important because Lombok's toString causes a recursive call which then results in the previously mentioned exception.

  • Related