chi*_*tiz 8 java hibernate hibernate-5.x
我有这个简单的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();
}
Run Code Online (Sandbox Code Playgroud)
问题是参数和某种程度上混乱或混合或处于错误位置时每个问题出现时我创建两个createAlias都至少有这样的标准(见下面的更新)
createAlias With Some Criterions
createAlias("school","s",JoinType.INNER_JOIN,Restrictions.eq("zipCode",1764))
createAlias("address","a",JoinType.LEFT_OUTER_JOIN,eq)
Run Code Online (Sandbox Code Playgroud)
生成的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
)
Run Code Online (Sandbox Code Playgroud)
您可以看到邮政编码值1764绑定到第一个参数address2_.FDL
binding parameter [1] as [INTEGER] - [1764]
Run Code Online (Sandbox Code Playgroud)
稍后,第二个参数cid被赋予fdl的正确先前值,即'N'
Message: binding parameter [2] as [VARCHAR] - [N]
Run Code Online (Sandbox Code Playgroud)
之后,为cid分配的第三个参数是1的正确的先前值
binding parameter [3] as [INTEGER] - [1]
Run Code Online (Sandbox Code Playgroud)
之后,zipCode这四个参数被分配了did的正确先前值,即2
binding parameter [4] as [INTEGER] - [2]
Run Code Online (Sandbox Code Playgroud)
当然generatesql匹配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
)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,绑定显然是错误的.
预期<---------------->现实
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
Run Code Online (Sandbox Code Playgroud)
我认为发生了什么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)
Run Code Online (Sandbox Code Playgroud)
环境
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)
Run Code Online (Sandbox Code Playgroud)
另一个类似的论坛
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
Run Code Online (Sandbox Code Playgroud)
UPDATE
即使是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();
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,绑定显然是错误的.
预期<---------------->现实
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'
Run Code Online (Sandbox Code Playgroud)
...同样的问题遇到了我已经看到很多论坛报告这个问题为什么hibernate不修复它?
org.hibernate.Criteria API被视为已弃用:
Hibernate提供了一个较旧的遗留
org.hibernate.CriteriaAPI,应该被视为已弃用.没有功能开发将针对这些API.最终,特定于Hibernate的标准功能将被移植为JPA的扩展javax.persistence.criteria.CriteriaQuery.
因此,org.hibernate.Criteria在未来版本中,您不应期望与API(包括错误修复)相关的大量工作.
我建议你迁移到JPA CriteriaQueryAPI.但是,我个人也不喜欢它,我总是直接使用JPQL/HQL或QueryDSL,我发现它是JPQL字符串和CriteriaQueryAPI 的高级冗余之间的非常好的平衡.