【问题标题】:Hibernate Criteria causes ORA-00918: column ambiguously definedHibernate Criteria 导致 ORA-00918:列定义不明确
【发布时间】:2011-10-10 12:48:39
【问题描述】:

我正在运行以下代码:

      Criteria crit = dao.getSesion().createCriteria(TAmbitos.class);
      crit.add( Restrictions.sqlRestriction("translate(upper(nombre), 'ÁÉÍÓÚ', 'AEIOU') like translate(upper(?),'ÁÉÍÓÚ', 'AEIOU')",
              param+"%", Hibernate.STRING));
      crit.add(Restrictions.eq("tipoAmbito", "Empresa"));

      crit.setFetchMode("TAmbitosByPais", FetchMode.JOIN);
      crit.createAlias("TAmbitosByPais", "TAmbitosByPais", CriteriaSpecification.LEFT_JOIN);
      crit.add(Restrictions.eq("TAmbitosByPais", ambito));

这导致ORA-00918: column ambiguously defined 异常。条件有一个表TAmbitos,它通过TAmbitosByPais 引用自己(任何给定的TAmbitos 行都有一个字段TAmbitosByIdPais,它引用另一个TAmbitos)。生成的 SQL 是:

SELECT this_.id_ambito AS id1_2_1_, this_.depende_empresa AS depende2_2_1_,
   this_.id_zona AS id3_2_1_, this_.pais AS pais2_1_,
   this_.id_cls_soc AS id5_2_1_, this_.tipo_ambito AS tipo6_2_1_,
   this_.nombre AS nombre2_1_, this_.clave_antigua AS clave8_2_1_,
   this_.desactivado AS desactiv9_2_1_,
   tambitosby1_.id_ambito AS id1_2_0_,
   tambitosby1_.depende_empresa AS depende2_2_0_,
   tambitosby1_.id_zona AS id3_2_0_, tambitosby1_.pais AS pais2_0_,
   tambitosby1_.id_cls_soc AS id5_2_0_,
   tambitosby1_.tipo_ambito AS tipo6_2_0_,
   tambitosby1_.nombre AS nombre2_0_,
   tambitosby1_.clave_antigua AS clave8_2_0_,
   tambitosby1_.desactivado AS desactiv9_2_0_
  FROM sac_conf.t_ambitos this_ LEFT OUTER JOIN sac_conf.t_ambitos tambitosby1_
       ON this_.pais = tambitosby1_.id_ambito
 WHERE TRANSLATE (UPPER (nombre), 'ÁÉÍÓÚ', 'AEIOU') LIKE
                                       TRANSLATE (UPPER (?), 'ÁÉÍÓÚ', 'AEIOU')
   AND this_.tipo_ambito = ?
   AND this_.pais = ?

正如您在 WHERE 子句中看到的那样,SQL 无法判断我引用的是什么“名词”字段。我可以通过在 sqlRestriction 中添加 this_ 来克服这个问题:

crit.add( Restrictions.sqlRestriction("translate(upper(this_.nombre), 'ÁÉÍÓÚ', 'AEIOU') like translate(upper(?),'ÁÉÍÓÚ', 'AEIOU')",
                  nombre+"%", Hibernate.STRING));

但我不知道这是否是最佳解决方案,因为我无法确定 SQL 是否将始终将查询表引用为 this_。还有另一种定义标准的方法,因此“名词”引用 TAmbitos.nombre 而不是TAmbitosByIdPais.nombre?

谢谢。

【问题讨论】:

    标签: java oracle hibernate ora-00918


    【解决方案1】:

    Hibernate Criteria API 支持这种情况下的特殊 {alias} 占位符:

    crit.add( Restrictions.sqlRestriction(
       "translate(upper({alias}.nombre), 'ÁÉÍÓÚ', 'AEIOU') like translate(upper(?),'ÁÉÍÓÚ', 'AEIOU')",
       param+"%", Hibernate.STRING)); 
    

    【讨论】:

    • 如果您像我一样想知道:是的,您必须按字面意思输入 {alias} 这不是 {yourTableAlias} 或 {myTableAlias} 它是一个特殊的占位符,就像刚才解释的 axtavt。
    • 就我而言,我已经完成了Restrictions.sqlRestriction("id in ...")id 需要替换为{alias}.id
    【解决方案2】:

    Documentation 救援:

    应用以 SQL 表示的约束。 任何出现的 {alias} 都会 被表别名替换。

    (强调我的)

    【讨论】:

    • Restrictionsdocs,我觉得SQLQuery不能用在Restriction.sqlQuery(String, ...)里。 SQLQuery 可以成为toString 的有效参数吗?
    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多