插入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
相关产品推荐
相关产品推荐

