You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

插入AssocTransportVehicleDriver时出现IdentifierGenerationException异常求助

解决Hibernate插入关联表时的IdentifierGenerationException异常

我来帮你分析问题并给出解决方案,作为Hibernate新手遇到这种复合主键的问题很正常,咱们一步步来:

异常原因

你遇到的org.hibernate.id.IdentifierGenerationException: null id generated for:class异常,核心问题出在这几点:

  • 你的assoc_transport_vehicle_driver表用的是复合主键(vehicle_id和tdi_id联合作为主键),Hibernate通过AssocTransportVehicleDriverId这个@Embeddable类来映射这个复合主键。
  • 你插入数据时只设置了transportDriverInfo和transportVehicleInfo关联实体,但没有给AssocTransportVehicleDriver的id字段赋值。加上关联字段上设置了insertable=false, updatable=false,Hibernate不会从关联实体中提取主键值填充复合ID,最终导致ID为null,触发异常。
  • 代码里还有个明显笔误:transportVehicleInfo1.setVehicleId(transportDriverInfoId),这里应该用transportVehicleInfoId而非transportDriverInfoId,否则会把车辆ID错误设成司机ID,后续关联肯定出问题。

嵌入式ID类的用途

那个AssocTransportVehicleDriverId类可不是没用的,它是JPA/Hibernate映射复合主键的标准方式:因为你的表没有单独的自增主键列,而是用两个外键联合做主键,必须用一个@Embeddable类封装这两个主键字段,让Hibernate能识别这个复合主键结构。

解决方法

你需要手动创建AssocTransportVehicleDriverId实例并赋值,然后绑定到AssocTransportVehicleDriver对象上,同时修复笔误。修改后的插入代码如下:

AssocTransportVehicleDriver obj=null;
if(transportVehicleInfoId != 0 && transportDriverInfoId != 0) {
    // 修复笔误:正确设置车辆ID
    TransportVehicleInfo transportVehicleInfo1 = new TransportVehicleInfo();
    transportVehicleInfo1.setVehicleId(transportVehicleInfoId);
    
    TransportDriverInfo transportDriverInfo1 = new TransportDriverInfo();
    transportDriverInfo1.setTdiId(transportDriverInfoId);
    
    obj= new AssocTransportVehicleDriver();
    // 关键步骤:创建并设置复合ID
    AssocTransportVehicleDriverId assocId = new AssocTransportVehicleDriverId();
    assocId.setVehicleId(transportVehicleInfoId);
    assocId.setTdiId(transportDriverInfoId);
    obj.setId(assocId);
    
    obj.setTransportDriverInfo(transportDriverInfo1);
    obj.setTransportVehicleInfo(transportVehicleInfo1);
    res=service.addAssocDriverVehicle(obj);
}

额外优化建议

如果你的关联实体(司机、车辆)已经在数据库中存在,建议直接从Session加载持久化实体,而不是新建对象只设置ID,这样更安全:

// 在service方法中获取Session后加载实体
TransportVehicleInfo transportVehicleInfo1 = currentSession.get(TransportVehicleInfo.class, transportVehicleInfoId);
TransportDriverInfo transportDriverInfo1 = currentSession.get(TransportDriverInfo.class, transportDriverInfoId);

这样能避免插入不存在的关联数据,同时Hibernate会自动管理关联关系的一致性。

内容的提问来源于stack exchange,提问作者bharath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:19:08