Spring 数据 JPA 和泛型

Spring Data JPA and Generics

我有一个看起来像这样的实体

@Entity(name = "encounter_pdf_export")
public class EncounterPDFExport<T extends Encounter> implements Serializable {

    public static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long pdfExportId;

    @Any(metaColumn = @Column(name = "encounter_type"))
    @Cascade(CascadeType.ALL)
    @AnyMetaDef(
            idType = "long",
            metaType = "string",
            metaValues = {
                    @MetaValue(value = "FooEncounter", targetEntity = FooEncounter.class)
            })
    @JoinColumn(name = "encounter_id")
    private T encounter;

我要扩展的抽象类型是:

public abstract class Encounter {

    public abstract Long getEncounterId();
}

这是我的 Spring 数据存储库

@Repository
public interface EncounterPDFExportRepository extends PagingAndSortingRepository<EncounterPDFExport, Long> {

    EncounterPDFExport findOneByEncounter_encounterId(@Param("encounterId") Long encounterId);
}

启动与 findOneByEncounter_encounterId 方法相关的应用程序时,我得到堆栈跟踪:

Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [encounter] on this ManagedType [com.iimassociates.distiller.domain.EncounterPDFExport]
    at org.hibernate.jpa.internal.metamodel.AbstractManagedType.checkNotNull(AbstractManagedType.java:144)
    at org.hibernate.jpa.internal.metamodel.AbstractManagedType.getAttribute(AbstractManagedType.java:130)
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:468)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:300)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:243)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:148)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:88)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:46)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:116)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:237)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:65)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:100)

我假设 Spring Data JPA 不支持 abstracted/generic 字段?如果是这种情况,创建 @Query 是否足够解决问题?

不确定这是否对任何人都有帮助,但我确实成功了。

  1. 删除了抽象 class 并使其成为具有单个 public getEncounterId() 方法的接口
  2. 修改FooEncounter实现上述接口
  3. 从 EncounterPDFExport 中删除了泛型 class
  4. 修改了 encounter 字段以利用上述接口而不是通用接口
  5. 显然,我在访问 FooEncounter 中的字段时遇到了一些 Hibernate bug/limitation。不过,在 EncounterPDFExport 中访问 Encounter 工作正常。我修改了我的 Spring Data JPA Repository 如下所示(注意 encounter.encounterId 发现的修改与刚刚遇到的修改):

    @Repository
    public interface EncounterPDFExportRepository extends PagingAndSortingRepository<EncounterPDFExport, Long> {
    
        EncounterPDFExport findOneByEncounter(@Param("encounter") Encounter encounter);
    }
    

有问题的 Hibernate 错误似乎与 https://jira.spring.io/browse/DATAJPA-836 有关。