首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向JPA CriteriaQuery添加联接

向JPA CriteriaQuery添加联接
EN

Stack Overflow用户
提问于 2021-09-16 10:23:17
回答 1查看 27关注 0票数 0

我的FlowStep对象上有一个CriteriaQuery。

代码语言:javascript
复制
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<FlowStep> cbQuery = cb.createQuery(FlowStep.class);
Root<FlowStep> flowStep = cbQuery.from(FlowStep.class);


List<Predicate> predicates = new ArrayList<>();

然后,我根据要过滤的内容添加许多谓词。

代码语言:javascript
复制
// add all the conditions to query
cbQuery.select(flowStep).where(predicates.toArray(new Predicate[0]));

我甚至添加了排序的东西。

代码语言:javascript
复制
cbQuery.orderBy(orders);

Query query = em.createQuery(cbQuery);

List<FlowStep> resultList = query.getResultList();

但是我需要像这样添加一个连接:

代码语言:javascript
复制
select * from flowstep fs join flowinstance fi on fi.id = fs.flowinstanceid and fi.domainid = 'Test'

因此,我只想返回符合条件的流步骤,这些步骤在测试域中,域信息在表flowinstance中。如何将join添加到CriteriaQuery?

我看到了像这样的东西

代码语言:javascript
复制
Join<FlowStep, UUID> flowStepFlowInstanceJoin = flowStep.join(FlowInstance_.id);

但然后我需要在域上添加等于一个值的条件。

可以在JPQL标准查询上使用像上面这样的连接吗?

最初的答案是在谓词列表之前添加以下内容:

代码语言:javascript
复制
Join<FlowStep, FlowInstance> flowStepFlowInstanceJoin = flowStep.join("id", JoinType.LEFT);
flowStepFlowInstanceJoin.on(cb.equal(flowStepFlowInstanceJoin.get("domainid"), domain));

FlowStep有一个flowinstanceid列和字段,flowinstance有一个id字段。这可以编译,但不起作用。我得到一个错误“无法连接到基本类型的属性”。所以在FlowStep和FlowInstance之间需要有一对多的关系?一个FlowInstance有很多流程步骤,所以可能

代码语言:javascript
复制
@Column(name = flowinstanceid)
private UUID flowInstanceId;

FlowStep中的类是否需要更改为JoinColumn?并添加一个OneToMany或ManyToOne关系来实现上述连接?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-17 13:58:54

CriteriaBuilder join two tables with a custom conditionJPA many-to-one relation - need to save only Id提出了解决方案。

在FlowStep类中,我们需要添加FlowInstance对象和ManyToOne注释:

代码语言:javascript
复制
@JoinColumn(name = FLOW_INSTANCE_ID, insertable = false, updatable = false)
@ManyToOne(targetEntity = FlowInstance.class, fetch = FetchType.EAGER)
@JsonIgnore
private FlowInstance flowInstance;

注意:该类已经有了一个用于UUID类型的流实例id的字段,但是似乎对于ManyToOne关系来说,类FlowInstance的字段是必需的。

然后,在构建JPA查询时:

代码语言:javascript
复制
Join<FlowStep, FlowInstance> flowStepFlowInstanceJoin = flowStep.join("flowInstance", JoinType.INNER); 
flowStepFlowInstanceJoin.on(cb.equal(flowStepFlowInstanceJoin.get("domainId"), domain));

这放在

代码语言:javascript
复制
Root<FlowStep> flowStep = cbQuery.from(FlowStep.class);

线路。这使得它可以工作。非常重要的一点是,连接是INNER类型的,这样它就只返回具有所需域的步骤。LEFT将返回具有不需要的域的步骤,而RIGHT将返回与具有需要的域的步骤一样多的空行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69206705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档