Criteria Builder在嵌套实体为空时不返回实体。

huangapple 未分类评论44阅读模式
英文:

Criteria Builder does not return an entity when nested entity is null

问题

我有一个名为"caseHeader"的根实体,它包含一些嵌套实体(--> activeCase --> customer)。我正在使用条件构建器来动态搜索这些实体。我试图创建一个谓词,可以匹配包括嵌套实体(client)中的一个字段在内的多个字段。所以我尝试了这样的代码:

criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.equal(caseHeaderRoot.get("activeCase").get("customer").get("uniqueId"), "1234")
)

嗯,如果客户不为空,那么这个代码按预期工作。它会返回id等于"1234"或客户唯一id等于"1234"的实体。但是,如果存在一个id为"1234"且没有客户的实体,即使第一个谓词应该匹配它,这个实体也不会包含在结果集中。

我试图像这样检查空客户:

criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.and(
    criteriaBuilder.isNotNull(caseHeaderRoot.get("activeCase").get("customer")),
    criteriaBuilder.equal(caseHeaderRoot.get("activeCase").get("customer").get("uniqueId"), "1234")
  )
)

我还尝试使用元模型而不是字符串,以避免模型中的拼写错误,但结果是一样的。

我漏掉了什么?为什么空客户导致查询不匹配该实体,即使根实体的ID会匹配第一个谓词呢?

英文:

I have a root entity "caseHeader" that have some nested entities (--> activeCase --> customer). I am using a criteria builder to dynamically search over those entities. I am trying to create a predicate that will match several fields including one of the fields of the nested entity (client). So I tried something like this:

criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.equal(caseHeaderRoot.get("activeCase").get("customer").get("uniqueId"), "1234")
)

Well, if the customer is not null, then this works as expected. It returns entities with id or customer unique id equal to "1234". But if there is an entity with id "1234" and no customer, this entity is not included in the result set, even though the first predicate should match it.

I tried to check for null customer like this:

criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.and(
    criteriaBuilder.isNotNull(caseHeaderRoot.get("activeCase").get("customer")),
    criteriaBuilder.equal(caseHeaderRoot.get("activeCase").get("customer").get("uniqueId"), "1234")
  )
)

I tried also to use the meta-model instead of the strings, to avoid typos in my model, but the result was the same.

What am I missing? Why the null customer makes the query to not match that entity even though the root entity ID would match the first predicate.

答案1

得分: 0

我已经找出了问题所在,以防其他人也陷入同样的陷阱,下面是我是如何解决的...

现在我使用左连接将根节点与activeCase和customer连接起来,像这样:

Join customerJoin = caseHeaderRoot.join("activeCase", JoinType.LEFT).join("customer", JoinType.LEFT);
criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.equal(customerJoin.get("uniqueId"), "1234")
)

我认为这也可能对其他人有帮助。 Criteria Builder在嵌套实体为空时不返回实体。

英文:

I have found out what it was, in case someone fall into the same trap, here is how I fixed it...

Now I join the root with left joins for the activeCase and customer like this:

Join customerJoin = caseHeaderRoot.join("activeCase", JoinType.LEFT).join("customer", JoinType.LEFT);
criteriaBuilder.or(
  criteriaBuilder.equal(caseHeaderRoot.get("id"), "1234"),
  criteriaBuilder.equal(customerJoin.get("uniqueId"), "1234")
)

I think this could help also others. Criteria Builder在嵌套实体为空时不返回实体。

huangapple
  • 本文由 发表于 2020年7月27日 07:32:02
  • 转载请务必保留本文链接:https://java.coder-hub.com/63106862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定