Hibernate Criteria API 中使用子选择处理 NULL

发布于 2024-08-27 15:20:31 字数 1639 浏览 13 评论 0原文

我正在构造一个 Hibernate Criterion,使用子选择如下,

DetachedCriteria subselect =
    DetachedCriteria.forClass(NhmCode.class, "sub"); // the subselect selecting the maximum 'validFrom'
subselect.add(Restrictions.le("validFrom", new Date())); // it should be in the past (null needs handling here)
subselect.add(Property.forName("sub.lifeCycle").eqProperty("this.id")); // join to owning entity
subselect.setProjection(Projections.max("validFrom"));  // we are only interested in the maximum validFrom

Conjunction resultCriterion = Restrictions.conjunction();
resultCriterion.add(Restrictions.ilike(property, value)); // I have other Restrictions as well
resultCriterion.add(Property.forName("validFrom").eq(subselect)); // this fails when validFrom and the subselect return NULL

return resultCriterion;

到目前为止它工作正常,但是当 validFrom 和子选择结果为 NULL 时,return 语句之前的最后一行的限制为 false。

我需要的是一个能够正确处理这种情况的版本。可能通过应用 NVL 或合并或类似方法。

我该怎么做?

更新: ----------------------------

Péters 的想法与 sqlRestriction 产生这样的 where 子句:

        ...
        and (
            nhmcode1_.valid_from = (
                select
                    max(sub_.valid_from) as y0_ 
                from
                    nhm_code sub_ 
                where
                    sub_.valid_from<=? 
                    and sub_.lc_id=this_.id
            ) 
            or (
                nhmcode1_.valid_from is null 
                and sub.validFrom is null
            )
        )
        ...

反过来又产生:

ORA -00904:“SUB_”。“VALIDFROM”:ungültiger Bezeichner

错误消息,含义为“无效标识符”

I'm constructing a Hibernate Criterion, using a subselect as follows

DetachedCriteria subselect =
    DetachedCriteria.forClass(NhmCode.class, "sub"); // the subselect selecting the maximum 'validFrom'
subselect.add(Restrictions.le("validFrom", new Date())); // it should be in the past (null needs handling here)
subselect.add(Property.forName("sub.lifeCycle").eqProperty("this.id")); // join to owning entity
subselect.setProjection(Projections.max("validFrom"));  // we are only interested in the maximum validFrom

Conjunction resultCriterion = Restrictions.conjunction();
resultCriterion.add(Restrictions.ilike(property, value)); // I have other Restrictions as well
resultCriterion.add(Property.forName("validFrom").eq(subselect)); // this fails when validFrom and the subselect return NULL

return resultCriterion;

It works ok so far, but the restriction on the last line before the return statement is false when validFrom and subselect result in NULL.

What I need is a version which handles this case as true. Possibly by applying a NVL or coalesce or similar.

How do I do this?

Update: ----------------------------

Péters idea with the sqlRestriction results in a where clause like this:

        ...
        and (
            nhmcode1_.valid_from = (
                select
                    max(sub_.valid_from) as y0_ 
                from
                    nhm_code sub_ 
                where
                    sub_.valid_from<=? 
                    and sub_.lc_id=this_.id
            ) 
            or (
                nhmcode1_.valid_from is null 
                and sub.validFrom is null
            )
        )
        ...

which in turn result in:

ORA-00904: "SUB_"."VALIDFROM": ungültiger Bezeichner

the error message meaning 'invalid identifier'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逆流 2024-09-03 15:20:31

您可以尝试这样的方法而不是有问题的行:

resultCriterion.add(
  Restrictions.or(
    Restrictions.and(
      Restrictions.isNull("validFrom"),
      Restrictions.sqlRestriction("sub.validFrom is null")
    ),
    Property.forName("validFrom").eq(subselect)
  )
);

这可能不会立即起作用,但希望有帮助。

You could try something like this instead of the problematic line:

resultCriterion.add(
  Restrictions.or(
    Restrictions.and(
      Restrictions.isNull("validFrom"),
      Restrictions.sqlRestriction("sub.validFrom is null")
    ),
    Property.forName("validFrom").eq(subselect)
  )
);

This may not work straight away, but hopefully helps.

黒涩兲箜 2024-09-03 15:20:31

看起来这确实是 Criteria API 的又一限制。

我发现为这种事情创建自己的标准(或一组标准)实际上并不困难。

最大的问题是您基本上必须在没有任何文档的情况下进行。获取一些与您想要执行的操作类似的实现。调整它,看看它生成什么 SQL,冲洗并重复。

不好玩,但它有效。

抱歉,我没有可用于解决问题中的问题的实现。

It really looks like this is one more limitation of the Criteria API.

I found that it is actually not that difficult to create your own Criterion (or set of Criterions) for this kind of thing.

The biggest problem is you'll basically have to go without any documentation. Grab some Implementation which is similar to what you want to do. Tweek it, see what sql it generates, rinse and repeat.

Not fun, but it works.

Sorry I don't have the implementation available for the problem in the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文