Hibernate继承:一对多关联两个子类失效问题排查
JPA单表继承关联子类集合时的类型混淆问题解决
我来帮你拆解这个问题的核心原因,以及对应的解决办法:
问题根源
你采用了JPA的单表继承策略(@Inheritance默认就是单表继承),所有Beneficiary子类(BeneficiaryCompany和BeneficiaryPerson)的数据都存在同一个beneficiary表中,仅靠type鉴别列区分类型。
但在Transaction类的两个@OneToMany关联里,你只指定了targetEntity和外键transaction_id,却没有告诉Hibernate要根据鉴别列type过滤数据。Hibernate加载集合时,只会匹配transaction_id对应的记录,不会自动识别type的值——这就导致不管是type='company'还是type='person'的记录,只要外键匹配,都会被塞进第一个集合beneficiaryCompanies里。
当Hibernate尝试加载第二个集合beneficiaryPeople时,发现有些记录已经被实例化为BeneficiaryCompany类型,现在要强制转换成BeneficiaryPerson,自然就抛出org.hibernate.WrongClassException了。
解决方案:添加@Where注解过滤鉴别列
你需要在每个@OneToMany关联上加上@Where注解,显式指定过滤条件,让Hibernate只加载对应类型的记录。修改后的Transaction类代码如下:
@Data @AllArgsConstructor @Entity @Table(name="transaction") public class Transaction { public Transaction() {} @Id private String id; private String description; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = BeneficiaryCompany.class) @JoinColumn(name="transaction_id", nullable = false) @Where(clause = "type='company'") // 只加载type为company的记录 private Set<BeneficiaryCompany> beneficiaryCompanies; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = BeneficiaryPerson.class) @JoinColumn(name="transaction_id", nullable = false) @Where(clause = "type='person'") // 只加载type为person的记录 private Set<BeneficiaryPerson> beneficiaryPeople; }
补充说明
targetEntity属性仅用于告知JPA关联的目标实体类,不会自动过滤数据,因为单表继承下所有子类共享同一张表,必须手动添加过滤条件区分类型。@Where是Hibernate的扩展注解,会在生成SQL查询时自动追加WHERE type='xxx'的条件,确保每个集合只加载对应类型的实例,彻底避免类型混淆问题。
内容的提问来源于stack exchange,提问作者B_Osipiuk
相关产品推荐
相关产品推荐

