Kevin's Java Life

喝一杯咖啡,生活变得从容和清新
随笔 - 3, 文章 - 12, 评论 - 1, 引用 - 0
数据加载中……

HQL问题与解答

HQL是Hibernate的重要特色,对象查询语言与SQL多有不同,而官方又没有提供很详细的手册,所以经常会遇到不同的问题,这里记录下我自己经历过的HQL问题和查找到的答案。


没有外键关联的两个表做联合查询

有两个表Zsplcxxb(流程表)和Lcsplsb(流程审批历史表),两个表都有lcbh(流程编号),但是没有设置外键关联,做以下的查询:

from Zsplcxxb as a inner join Lcsplsb as b on a.lczbh = b.lczbh and b.blrbh='' and b.blrbh != a.sqrbh and a.clrbh != '' order by a.zhgxrq desc

出现以下问题(在HibernateConsole中运行)

1 errors occurred while listing (and calling getPathNames).
net.sf.hibernate.QueryException: 
outer or full join must be followed by path expression [from com.aljoin.xzsp.entity.Zsplcxxb as a inner join Lcsplsb as b on a.lczbh = b.lczbh and b.blrbh='' and b.blrbh != a.sqrbh and a.clrbh != '' order by a.zhgxrq desc]

原因
 只有两个entity有association的状况下,才能使用join。比如Zsplcxxb and Lcsplsb有many-to-one的association
另:HQL中没有“on a.lczbh = b.lczbh”这样的语法

解决方法
1.改用where子句

from Zsplcxxb as a, Lcsplsb as b where a.lczbh = b.lczbh and b.blrbh=and b.blrbh != a.sqrbh and a.clrbh != ? order by a.zhgxrq desc

2.如果是left join or right join,好像只能用session.createSQLQuery() or NamedQuery直接执行Native SQL了。



新问题
 返回的List中每一项都是一个对象数组,包含了Zsplcxxb and Lcsplsb两个entity

原因:
 “inner join fetch”子句,则 Lcsplsb 读取后立即填充到 Zsplcxxb 中。
 “inner join”子句,则返回两个entity。而where子句等同于“inner join”子句

解决方法:加上Select语句
select from Zsplcxxb as a, Lcsplsb as b where a.lczbh = b.lczbh and b.blrbh=and b.blrbh != a.sqrbh and a.clrbh != ? order by a.zhgxrq desc



新问题
返回的Zsplcxxb entity有重复的。因为一个流程有多个审批记录,inner join 之后对应每个审批记录都会返回一样的流程。

解决方法:加上distinct语句
select distinct a from Zsplcxxb as a, Lcsplsb as b where a.lczbh = b.lczbh and b.blrbh=and b.blrbh != a.sqrbh and a.clrbh != ? order by a.zhgxrq desc



新问题
net.sf.hibernate.JDBCException: Could not execute query
java.sql.SQLException: 
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

原因

如果是SQL的话,使用 distinct a.* 即可。但是对于HQL,没法使用 * 来选择属性,于是Hibernate就认为a.zhgxrq没有出现在select 子句中。

解决方法
使用 order by entity.pk or order by entity 。(真是奇怪,能找到主键,其他属性为什么找不到?)
select distinct a from Zsplcxxb as a, Lcsplsb as b where a.lczbh = b.lczbh and b.blrbh=and b.blrbh != a.sqrbh and a.clrbh != ? order by a desc

参考文档:
1.javaworld@TW[問題]關於使用HQL left outer join
2.JavaEye:『出错』两个没有外键关联的表做inner join的时候 HQL语句出错
3.Hibernate官方论坛:Chapter 14. HQL: The Hibernate Query Language

posted on 2005-12-27 15:00 Kevin 阅读(1589) 评论(0)  编辑  收藏 所属分类: Hibernate


只有注册用户登录后才能发表评论。


网站导航: