Hibernate单表继承中CriteriaQuery关联子类属性报错求助
解决Hibernate单表继承中子类专属属性的关联查询问题
错误原因
直接从Root<VehicleEntity>调用join("passengerData")会报错,因为基类VehicleEntity并不存在passengerData属性,Hibernate的元数据仅识别当前ManagedType(此处为VehicleEntity)的属性。
正确实现方式
方法1:使用Treat将基类Root转换为子类类型
先把Root<VehicleEntity>转换为CarriageEntity类型的Root,再关联passengerData,同时添加鉴别器条件过滤出Carriage类型的记录:
CriteriaQuery<Tuple> cQ = cb.createTupleQuery(); Root<VehicleEntity> vehicleRoot = cQ.from(VehicleEntity.class); // 将基类Root转换为子类CarriageEntity的类型 Root<CarriageEntity> carriageRoot = cb.treat(vehicleRoot, CarriageEntity.class); // 关联passengerData(支持指定JoinType,比如LEFT) Join<CarriageEntity, PassengerDataEntity> passengerJoin = carriageRoot.join("passengerData", JoinType.LEFT); // 添加鉴别器条件,仅查询CARRIAGE类型的车辆 cQ.where(cb.equal(vehicleRoot.get("vehicle_type_id"), "CARRIAGE")); // 后续查询逻辑(例如选择字段、排序等)
方法2:在Join操作中直接使用Treat转换
如果不需要单独的子类Root,可在join时直接对路径进行treat转换:
CriteriaQuery<Tuple> cQ = cb.createTupleQuery(); Root<VehicleEntity> vehicleRoot = cQ.from(VehicleEntity.class); // 先将基类Root转换为CarriageEntity,再关联passengerData Join<CarriageEntity, PassengerDataEntity> passengerJoin = cb.treat(vehicleRoot, CarriageEntity.class).join("passengerData"); // 必须添加鉴别器过滤条件 cQ.where(cb.equal(vehicleRoot.get("vehicle_type_id"), "CARRIAGE")); // 后续查询逻辑
关键注意点
- 必须添加鉴别器字段过滤:数据库中存在多种类型的Vehicle记录,添加过滤条件可避免无意义的关联,同时保证查询结果仅包含Carriage类型的数据。
- 若需保留无
passengerData的Carriage记录,关联时使用JoinType.LEFT即可。
内容的提问来源于stack exchange,提问作者Marc Serret i Garcia
相关产品推荐
相关产品推荐

