簡體   English   中英

Spring 數據 JPA 規范搜索嵌套集合中的屬性

[英]Spring Data JPA Specification search for property in nested collection

假設我至少有兩個實體。

@Entity
public class Process {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String name;

    @ManyToAny(
            metaColumn = @Column(name = "node_type"),
            fetch = FetchType.LAZY
    )
    @AnyMetaDef(
            idType = "long", metaType = "string",
            metaValues = {
                    @MetaValue(targetEntity = Milestone.class, value = MILESTONE_DISC),
                    @MetaValue(targetEntity = Phase.class, value = PHASE_DISC)
            }
    )
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    @JoinTable(
            name = "process_nodes",
            joinColumns = @JoinColumn(name = "process_id", nullable = false),
            inverseJoinColumns = @JoinColumn(name = "node_id", nullable = false)
    )
    private Collection<ProcessNode> nodes = new ArrayList<>();

    ...
}

@Entity
@ToString
@DiscriminatorValue(MILESTONE_DISC)
public class Milestone implements ProcessNode {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Collection<ResultDefinition> results;

    @ToString.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @Transient
    private Process process;

...
}

現在我想使用 spring 數據 jpa 規范來查找(所有)具有名為“S5”的里程碑的進程。

請注意,Milestone 是一個 ProcessNode,還有另一個名為 Phase 的實體也是一個 ProcessNode。 這些可以包含在我的流程實體的“節點”集合中。

數據庫結構

我試着寫這樣的東西:

    public static Specification<Process> hasMilestoneWithName(final String milestoneName) {
    return (Specification<Process>) (root, query, criteriaBuilder) -> {
        Path<?> namePath = root.join("nodes").get("name");
        return criteriaBuilder.equal(namePath, milestoneName);
    };
}

這不起作用,但會拋出:

原因:java.lang.IllegalArgumentException:無法在此 ManagedType [com.smatrics.dffs.processservice.model.entities.Process] 上找到具有給定名稱 [nodes] 的屬性

我真的不知道如何使用 API。 示例通常指的是由 IDE 或 maven 生成的元模型,但我真的不想讓任何 static 生成資源。 請在沒有生成元模型的情況下使用 spring-data-jpa 規范幫助我解決這個問題。

另外,如果你能幫我寫 hql 那就太棒了。

謝謝!

我會建議一個更簡單的替代方案,自下而上:

  • 加載具有name=S5Milestone實體: findByName("S5")
  • 返回每個MilestoneProcess
  • 過濾掉重復項

或者您甚至可以保存一些 SQL 查詢,方法是不返回Milestone實體,而只返回每個MilestoneProcess ID,然后通過 ID 列表加載Process節點:

(本機) SQL 等效項將是

select *
from process
where id in (
  select process_id
  from milestone
  where name = 'S5'
)

不管我的解決方案如何,您的join對我來說看起來並不完全正確,但我無法指出哪里出了問題 - 也許 JPA 元模型上還有其他方法返回CollectionJoin 沒有把握。 可能是因為@ManyToAny不是 JPA 標准,所以 JPA 標准 API 不將nodes識別為有效的“可連接”字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM