Hibernate使用@OneToMany与@ManyToOne保存数据外键为Null问题咨询
问题根本原因
你配置的是双向一对多关联,@OneToMany(mappedBy = "foreignModuleId")的配置明确说明:关联关系的控制权在多端(Assessment实体的foreignModuleId属性),Hibernate只会以多端的该属性值作为外键字段的插入依据。
你当前组装数据时,仅填充了Module的assessments列表,所有Assessment实例的foreignModuleId属性均为null,因此插入数据库时外键字段自然为空,和数据库表结构、基础注解配置无关。
修复方案
方案1:调整关联维护逻辑(推荐,符合双向关联规范)
修改Module实体的addAssessment方法,添加Assessment时自动绑定关联的Module实例:
public void addAssessment(Assessment assessment) { assessments.add(assessment); // 新增这行,给Assessment设置所属Module assessment.setForeignModuleId(this); }
后续组装Module数据时,统一调用addAssessment方法添加Assessment实例,不要直接操作assessments列表,即可自动维护两端关联。
方案2:修改关联控制逻辑(如果不需要严格双向关联可以使用)
如果你不需要通过Assessment侧查询关联的Module,也可以把双向关联改为单向,直接删除Assessment侧的foreignModuleId属性以及对应的@ManyToOne注解,同时去掉Module的@OneToMany注解中的mappedBy属性,新增@JoinColumn配置:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "assessment_belongsTo_module", referencedColumnName = "module_id") private List<Assessment> assessments;
该配置下关联控制权在Module端,仅填充assessments列表即可自动插入外键值。
补充优化建议
你当前的DAO代码存在SessionFactory使用错误:每次调用upload方法都会关闭SessionFactory,第二次调用该方法时会报错。建议把factory.close()的逻辑移到应用销毁的钩子中,不要放在单次操作的finally块里。
内容的提问来源于stack exchange,提问作者Fanis G

