返回

Spring Boot 3 中处理 Hibernate 泛型实体异常的终极指南:常见问题解答

java

处理 Spring Boot 3 中 Hibernate 泛型实体异常的终极指南

前言

当从 Spring Boot 2.7 迁移到 Spring Boot 3 时,处理由 Hibernate 管理的泛型实体可能会遇到一个恼人的异常:

java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.Optional FachparameterRepository.findByFachcode(FachparameterFachCode)

本文将深入探讨这一异常的原因,并提供两种解决方案,帮助你解决这个问题。

异常的原因

该异常的根源在于泛型基类 FachparameterReference 中多个具体子类 (例如 FunktionReferenceFehlerReference) 具有相同属性名称 (fachCode)。当尝试使用 findByFachcode 方法查找子类特定记录时,Hibernate 无法确定使用哪个子类的 fachCode 属性。

解决方案 1:使用子类属性注释

一种解决方法是在子类中使用 @AttributeOverrides 注释覆盖基类的 fachCode 属性,并指定明确的子类属性名称:

@Entity
@Table(name = "FehlerReference")
public class FehlerReference extends FachparameterReference<FehlerFachId, FehlerFachCode> {

  @AttributeOverrides({
    @AttributeOverride(name = "fachCode", column = @Column(name = "FEHLER_CODE"))
  })
  // 其他代码
}

解决方案 2:使用 Hibernate 子类表继承

另一个解决方案是使用 Hibernate 的子类表继承功能,如下所示:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class FachparameterReference<FACHID extends FachparameterFachId<FACHID>, FACHCODE extends FachparameterFachCode<FACHCODE>>
            extends EntityBase {
  
  @Id
  @GeneratedValue(strategy = GenerationType.TABLE)
  private Long id;
  
  // 其他通用字段
}
@Entity
@Table(name = "FehlerReference")
public class FehlerReference extends FachparameterReference<FehlerFachId, FehlerFachCode> {

  @Column(name = "FEHLER_CODE", unique = true)
  private FehlerFachCode fachCode;
  
  // 其他字段
}

在第二种方法中,子类表需要与基类表具有相同的 id 列。确保 FachparameterReference 是一个抽象类,以防止为它创建表。

常见问题解答

  • 问:为什么泛型类在 Hibernate 中会造成问题?
    答:当存在具有相同属性名称的多个具体子类时,Hibernate 会感到困惑,无法确定使用哪个属性。
  • 问:我该如何选择哪种解决方案?
    答:两种解决方案都可行,你可以根据具体情况选择最合适的一种。如果子类数量较少,使用属性注释可能更容易。如果子类数量较多,使用子类表继承可能更可扩展。
  • 问:是否还有其他解决方法?
    答:使用自定义查询或投影方法来避免使用 findByFachcode 也是一种选择。
  • 问:子类表继承有什么优势?
    答:子类表继承有助于数据隔离和维护。每个子类都有自己的表,这可以提高性能和灵活性。
  • 问:属性注释与子类表继承有什么区别?
    答:属性注释覆盖了基类属性,而子类表继承创建了单独的表。属性注释更简单,但子类表继承更可扩展和灵活。

结论

通过使用子类属性注释或子类表继承,你可以解决 Spring Boot 3 中处理 Hibernate 泛型实体时出现的异常。本文提供了详细的解决方案,并回答了常见的疑问。掌握这些解决方案将使你能够自信地管理泛型实体,并充分利用 Hibernate 的功能。