Hibernate用oracle生成无效的sql

Posted

技术标签:

【中文标题】Hibernate用oracle生成无效的sql【英文标题】:Hibernate generates invalid sql with oracle 【发布时间】:2013-05-29 14:06:24 【问题描述】:

我正在使用带有 Oracle11g 的休眠 4.2.1。在 NamedQuery 的转换过程中,hibernate 显然会生成一个无效的 SQL 语句。 NamedQuery 如下所示:

SELECT retenues FROM EnsembleRetenuesPrestation retenues
WHERE EXISTS (SELECT calcul FROM CalculRetenueGlobale calcul
              WHERE calcul.id.payementPrestation.id = :payementId
              AND calcul.id.ensembleRetenuesPrestation.id = retenues.id)

CalculRetenueGlobale 是 EnsembleRetenuesPrestation 和 PayementPrestation 的连接表(带有一些附加字段。所以它是一个真实的实体。)。它使用嵌入键作为主键,其中包含两个实体 CalculRetenueGlobale 和 PayementPrestation。

生成的SQL如下:

select
    ensemblere0_.ERP_ID_ENSEMBLE_RET_PREST as ERP1_24_,
    ensemblere0_.ERP_AAAAMM_ARRERAGES as ERP2_24_,
    ensemblere0_.ERP_CODE_CALCUL_SIMUL as ERP3_24_,
    ensemblere0_.ERP_ID_EXCEDENT_RETENUE as ERP19_24_,
    ensemblere0_.ERP_FLAG_5E_TRANCHE_CESSION as ERP4_24_,
    ensemblere0_.ERP_FLAG_ARRERAGES as ERP5_24_,
    ensemblere0_.ERP_MONTANT_APRES_RETENUES as ERP6_24_,
    ensemblere0_.ERP_MONTANT_AVANT_RETENUES as ERP7_24_,
    ensemblere0_.ERP_MONTANT_CESSIBLE as ERP8_24_,
    ensemblere0_.ERP_MONTANT_INCESS_INSAISISS as ERP9_24_,
    ensemblere0_.ERP_MONTANT_SAISISSABLE as ERP10_24_,
    ensemblere0_.ERP_RETENUE_ACOMPTE as ERP11_24_,
    ensemblere0_.ERP_RETENUE_ACOMPTE_FIXE as ERP12_24_,
    ensemblere0_.ERP_RETENUE_CONJOINT_TIERS as ERP13_24_,
    ensemblere0_.ERP_RETENUE_FAILLITE as ERP14_24_,
    ensemblere0_.ERP_RETENUE_SURENDETTEMENT as ERP15_24_,
    ensemblere0_.ERP_SOM_RET_ALIM as ERP16_24_,
    ensemblere0_.ERP_SOM_RET_CESSION as ERP17_24_,
    ensemblere0_.ERP_SOM_RET_SAISIES as ERP18_24_ 
from
    CCRSC.ENSEMBLE_RET_PREST ensemblere0_ 
where
    exists (
        select
            (calculrete1_.CAL_ID_CREANCE,
            calculrete1_.CAL_ID_ENSEMBLE_RET_PREST,
            calculrete1_.CAL_ID_PAIEMENT)
        from
            CCRSC.CALC_RET_GLOBALE calculrete1_ 
        where
            calculrete1_.CAL_ID_PAIEMENT=1
            and calculrete1_.CAL_ID_ENSEMBLE_RET_PREST=ensemblere0_.ERP_ID_ENSEMBLE_RET_PREST
    )

结果是 ORA-00907:缺少右括号。如果我删除这部分中的两个括号,我可以毫无问题地执行查询(例如在 SQLDeveloper 中):

select
    (calculrete1_.CAL_ID_CREANCE,
     calculrete1_.CAL_ID_ENSEMBLE_RET_PREST,
     calculrete1_.CAL_ID_PAIEMENT)

我只能找到一个老问题 (https://hibernate.atlassian.net/browse/HHH-2409),但在这种情况下,他们责怪 'AS' 关键字,这在这种情况下似乎不是问题。

有没有人遇到过类似的问题?这可能是映射问题吗?

提前致谢,

亚历克斯

【问题讨论】:

听起来像 oracle 查询解析器又变得讨厌了.. ;) 【参考方案1】:

将字段列表放在括号中即使是微不足道的查询也会产生错误,因此不是 Oracle 错误地解析了查询。

select (1,2,3) FROM DUAL

为旧版本的 Hibernate 建议的解决方法是返回文字值而不是 EXISTS() 中的字段。 (https://hibernate.atlassian.net/browse/HHH-2845)

SELECT retenues FROM EnsembleRetenuesPrestation retenues
WHERE EXISTS (SELECT 1 FROM CalculRetenueGlobale calcul
              WHERE calcul.id.payementPrestation.id = :payementId
              AND calcul.id.ensembleRetenuesPrestation.id = retenues.id)

(https://hibernate.atlassian.net/browse/HHH-5998) 中也提到了该问题

【讨论】:

以上是关于Hibernate用oracle生成无效的sql的主要内容,如果未能解决你的问题,请参考以下文章

eclipse 怎么用hibernate 反向生成实体类

Hibernate--JavaBean.hbm.xml配置

hibernate-------------------oracle问题

spring boot hibernate查询无效用户错误

Hibernate 5 ID AUTO 生成类型为 Oracle 作为序列和 MySQL 作为身份

用于从序列生成 id 的 Oracle 触发器的 HIbernate 问题