【问题标题】:NULL handling with subselect in Hibernate Criteria API在 Hibernate Criteria API 中使用 subselect 处理 NULL
【发布时间】:2011-02-05 07:40:45
【问题描述】:

我正在构建一个 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和subselect导致NULL时,return语句前最后一行的限制为false。

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

我该怎么做?

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

带有 sqlRestriction 的 Péters 想法导致了这样的 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

错误信息意思是“无效的标识符”

【问题讨论】:

标签: hibernate null criteria subquery nvl


【解决方案1】:

您可以尝试这样的方法来代替有问题的行:

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

这可能不会立即奏效,但希望有所帮助。

【讨论】:

  • 嗨,彼得,不幸的是,这只是解决方案的 50%。为了符合我的要求,它需要是: resultCriterion.add(Restrictions.or(Restrictions.and( Restrictions.isNull("validFrom"), Restrictions.isNull(subselect)), Property.forName("validFrom").eq(子选择)));但是 isNull 不能接受子查询(如果可以的话,它可能会在 sql 中复制 suquery,这会很丑陋,尽管它不会杀死我)。
  • @Jens 我刚刚更新了示例以(希望)处理这个问题。
【解决方案2】:

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

我发现为这类事情创建自己的 Criterion(或 Criterion 集)实际上并不难。

最大的问题是您基本上必须在没有任何文档的情况下使用。获取一些与您想要做的类似的实现。 Tweek 它,查看它生成的 sql,冲洗并重复。

不好玩,但很管用。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    相关资源
    最近更新 更多