【发布时间】:2020-11-23 13:27:41
【问题描述】:
假设我至少有两个实体。
@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 data 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 生成的元模型,但我真的不希望有任何静态生成的资源。请在没有生成元模型的情况下使用 spring-data-jpa 规范帮助我解决这个问题。
如果你能帮我写 hql 那就太棒了。
谢谢!
【问题讨论】:
标签: java spring hibernate spring-data-jpa criteria