Java Hibernate Bug错误的参数绑定

Java Hibernate Bug Wrong Parameter Binding

我有这个简单的 Hibernate 代码。

public List<Student>bug(){
    //SimpleCriteria
    final Criterion eq = and(Restrictions.eq("fdl","N"),Restrictions.eq("cid",1),Restrictions.eq("did",2));
    return currentSession().createCriteria(Student.class)                
           .createAlias("school","s",JoinType.INNER_JOIN,Restrictions.eq("zipCode",1764))               
           .createAlias("address","a",JoinType.LEFT_OUTER_JOIN,eq)
           .setProjection(addProjection("id"))
           .setResultTransformer(transformer(Student.class))                
           .list();
}      

问题是参数和不知何故混乱或混合或位置错误当我创建两个 createAlias 都至少符合这样的标准时出现问题(请参阅下面的更新)

根据一些标准创建别名

createAlias("school","s",JoinType.INNER_JOIN,Restrictions.eq("zipCode",1764))               
createAlias("address","a",JoinType.LEFT_OUTER_JOIN,eq)

生成的 sql 看起来不错..

select
    this_.ID as y0_ 
from
    student this_ 
left outer join
    address address2_ 
        on this_.C05=address2_.ID 
        and (
            (
                address2_.FDL=? 
                and address2_.CID=? 
                and address2_.DID=?
            ) 
        ) 
inner join
    school school_ 
        on this_.C03=school_.ID 
        and (
            school_.C06=? //ZIPCODE
        )

即使我看到 log4j,我也能看到错误的绑定

您可以看到邮政编码值 1764 绑定到第一个参数 address2_.FDL

binding parameter [1] as [INTEGER] - [1764]

稍后,第二个参数 cid 被分配给 fdl 的正确先前值,即 'N'

Message: binding parameter [2] as [VARCHAR] - [N]

稍后为执行的第三个参数分配正确的 cid 先前值 1

binding parameter [3] as [INTEGER] - [1]

稍后为 zipCode 的四个参数分配正确的先前值 did,即 2

binding parameter [4] as [INTEGER] - [2]

当然生成sql匹配log4j绑定

select
    this_.ID as y0_ 
from
    student this_ 
left outer join
    address address2_ 
        on this_.C05=address2_.ID 
        and (
            (
                address2_.FDL=1764 
                and address2_.CID='N'
                and address2_.DID=1
            ) 
        ) 
inner join
    school school_ 
        on this_.C03=school_.ID 
        and (
            school_.C06=2 //ZIPCODE
        )

如您所见,绑定显然是错误的。

预期<---------------->现实

1 parameter fdl should be bind to 'N' but is bind to zipCode value which is 1764
2 parameter cid should be bind to 1 but is bind to fdl value which is 'N'
3 parameter did should be bind to 2 but is bind to cid value which is 1
4 parameter zipCode should be bind to 1764 but is bind to did value which is 2

我认为 Hibernate 出于某种原因混合了参数位置。

遇到这个问题时我使用的是 Hibernate 4.3.4,但我看到一个类似的错误已在 5.2.2 中修复https://hibernate.atlassian.net/browse/HHH-10991,我升级到 Hibernate 5.2.2 后遇到了同样的问题已经看到很多论坛报告这个问题为什么hibernate不修复它?当然我有解决方法,但这个问题很烦人

如果我使用 2 createAlias 而不是标准,一切都会像预期的那样工作

createAlias("school","s",JoinType.INNER_JOIN,Restrictions.eq("zipCode",1764))               
createAlias("address","a",JoinType.LEFT_OUTER_JOIN)

环境

Java: 1.8.0_74; Java HotSpot(TM) 64-Bit Server VM 25.74-b02
Hibernate 5.2.2 and 4.3.4 tested in both.
Netbeans NetBeans IDE 8.1 (Build 201510222201)

其他类似论坛

https://forum.hibernate.org/viewtopic.php?f=1&t=947018
https://forum.hibernate.org/viewtopic.php?f=1&t=971534
https://hibernate.atlassian.net/browse/HHH-2496
https://hibernate.atlassian.net/browse/HHH-1743

更新

2个参数也出错

public List<Student>bug(){
    return currentSession().createCriteria(Student.class)                
     .createAlias("school","s",JoinType.INNER_JOIN,Restrictions.eq("zipCode",1764))               
     .createAlias("address","a",JoinType.LEFT_OUTER_JOIN,Restrictions.eq("fdl","N"))
     .setProjection(addProjection("id"))
     .setResultTransformer(transformer(Student.class))                
     .list();
}      

如您所见,绑定显然是错误的。

预期<---------------->现实

1 parameter fdl should be bind to 'N' but is bind to zipCode value which is 1764
2 parameter zipCode should be bind to 1764 but is bind to fdl value which is 'N'

...我遇到了同样的问题我看到很多论坛报告这个问题为什么休眠不修复它?

org.hibernate.Criteria API 被认为已弃用:

Hibernate offers an older, legacy org.hibernate.Criteria API which should be considered deprecated. No feature development will target those APIs. Eventually, Hibernate-specific criteria features will be ported as extensions to the JPA javax.persistence.criteria.CriteriaQuery.

因此,您不应期望在未来的版本中有很多与 org.hibernate.Criteria API(包括错误修复)相关的工作。

我建议您迁移到 JPA CriteriaQuery API。但是,我个人也不喜欢它,我总是直接使用 JPQL/HQL 或 QueryDSL,我发现它在 JPQL 字符串性和 CriteriaQuery [=29 的高冗长性之间取得了很好的平衡=]秒。