hibernate对union查询bug

来源:互联网 发布:360里有个网络监控 编辑:程序博客网 时间:2024/06/06 00:40

union关键词的介绍

union 是对多个select查询的结果进行组合
以union 连接两个select语句为例
两个select语句单独排序:
union左右的select语句中如果谁有order by ..limit..其必须单独用括号把这个select语句括起来;
两个select语句可以对不同的colName进行升序或者降序, 互不影响 ;
order by colName其后必须要有 limt 9999(否则order总是按升序排),数字可以根据需要取;
后面的select结果集是在前一个select结果集之后。
整体排序 :
order by 必须加在最后一条select的后面;
union 两边的select语句加不加括号都是可以的;
如果有括号,order by..[limit 9999]必须要在括号外面,因为对整体排序;
整体排序中,limit…是可选的。

hibernate的bug

在单独排序中,如果第一个select语句要排序则需要order by..limit,没错吧,
根据规则,还需要用括号括起来, bug coming!!!!

An SQLQuery surrounded by brackets:sessionFactory.getCurrentSession().createSQLQuery("(select * from MyTable)").list();gives this NPE:java.lang.NullPointerExceptionat org.hibernate.engine.jdbc.internal.BasicFormatterImpl$FormatProcess.isFunctionName(BasicFormatterImpl.java:376)at org.hibernate.engine.jdbc.internal.BasicFormatterImpl$FormatProcess.openParen(BasicFormatterImpl.java:357)at org.hibernate.engine.jdbc.internal.BasicFormatterImpl$FormatProcess.perform(BasicFormatterImpl.java:156)at org.hibernate.engine.jdbc.internal.BasicFormatterImpl.format(BasicFormatterImpl.java:91)at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:101)at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:95)BasicFormatterImpl line 155 contains:else if ( "(".equals( token ) ) {        openParen();}The openParen function starts with this code:private void openParen() {    if ( isFunctionName( lastToken ))    ...    }The "(" bracket is the first token in the query, the lastToken is therefore null and calling the isFunctionName with a null value causes the NPE.Known workaround: enclose the query with a 2nd select * from : select * from (select * from MyTable) as MyAlias.FYI, the query we used contained a union of 2 tables : (select * from MyTable union select * from MyTableCopy) order by MyColumn, hence requiring the brackets.

意思就是:第一个select语句加了"()"就会抛NPE异常!

解决办法

既然我们知道第一个select如果需要排序,就必须要加“()”,但hibernate的bug不让我们在第一个语句中加“()”。
然后我想到,不如我们在第一个select语句的前面再加一个select语句。让原来“第一个select语句”变成“第二个select语句”,而hibernate的bug只是针对“第一个select语句”。
那么后加的“第一个select语句”需要什么讲究?

不能有order by…limit..也就没有“()”了;
不能对原来的结果集有影响,所以不能查询到结果。

实例

try{ StringBuilder hql  = new StringBuilder (100); hql.append("select * from  business where restaurant_id=-1111 union "); hql.append("(select * from business where identifier = 5 and           deliver_time IS NULL order by created_at)");hql.append(" union ");hql.append("(select * from business where identifier =5 and deliver_time is not null order by deliver_time desc limit 999)");}

select * from business where restaurant_id=-1111

这句select语句是后加的,并且查不到结果

0 0