使用InheritanceType.JOINED继承策略时Hibernate关联查询选错表如何解决
问题根因
你遇到的是Hibernate 5.4.x版本针对JOINED继承策略的已知映射逻辑缺陷:当关联字段定义在父类实体、而@OneToMany关联目标为子类实体时,Hibernate生成SQL时错误地从子类表读取父类定义的外键字段,没有自动识别外键归属父类对应的表。
解决方案(优先JPA标准实现)
方案1:使用JPA标准
@AssociationOverride注解覆写子类的关联映射(首推)
该注解是JPA规范原生提供的,用于覆写从父类继承的关联属性的映射配置,显式指定外键列所在的表即可。在每个继承BaseAttributeEntity的子类上添加该注解:@Entity @Table(name = "SpecialAttributes") @AssociationOverride( name = "containerEntity", // 指定要覆写的继承自父类的关联属性名 joinColumns = @JoinColumn( name = "containerId", // 外键列名 table = "Attributes" // 显式指定外键列所在的表为父类对应的表 ) ) public class SpecialAttributeEntity extends BaseAttributeEntity { // ... 原有属性 }另一个子类
AnotherSpecialAttributeEntity也做相同配置即可。配置完成后Hibernate生成关联SQL时会自动从Attributes表读取containerId字段,不会再去子类表查找。方案2:调整
@OneToMany关联配置
如果不想修改子类,可以在ContainerEntity的集合属性上放弃mappedBy配置,显式指定关联列的归属(同样为JPA标准实现):@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn( name = "containerId", table = "Attributes", referencedColumnName = "id" ) private Set<SpecialAttributeEntity> specialAttributes = new HashSet<>();注意:该方案会将关联关系的维护方改为
ContainerEntity,需要调整业务中关联属性的赋值逻辑方案3:升级Hibernate版本
该映射bug在Hibernate 5.5.0及以上版本已被官方修复,无需修改任何代码配置即可正常生成正确的关联SQL。如果项目允许升级依赖,可直接将Hibernate版本升级至5.5.0.Final或更高版本。
内容的提问来源于stack exchange,提问作者Y. Sobelman
相关产品推荐
相关产品推荐

