hibernate hql 的case when 里不支持子查询吗

空白-键 2014-06-12 09:40:43
如下语句报错


select t, case when t.targetType=0 then
(select a.name from MarketApp a where a.id = t.target ) else '' end
from ThemeComponent t where t.theme.id = 1


jsp页面报如下错

java.lang.NullPointerException
at org.hibernate.hql.internal.ast.tree.CaseNode.getDataType(CaseNode.java:39)
at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:152)
at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:859)
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:649)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:663)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:105)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:80)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1777)


后台报如下错

[2014-06-12 09:29:37 ERROR] [http-8080-3] org.hibernate.hql.internal.ast.ErrorCounter.reportError(50) | <AST>:0:0: unexpected AST node: query
<AST>:0:0: unexpected AST node: query
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1363)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.caseExpr(HqlSqlBaseWalker.java:5074)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.arithmeticExpr(HqlSqlBaseWalker.java:3199)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2332)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2145)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1451)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:571)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)


如果去掉子查询,比如改为如下就不会有问题

select t, case when t.targetType=0
then t.name else '' end
from ThemeComponent t where t.theme.id = 1

...全文
304 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
空白-键 2014-06-12
  • 打赏
  • 举报
回复
引用 4 楼 defonds 的回复:
我没有看到查询解析器的配置
我搞定了,是支持子查询的。 org.hibernate.hql.internal.ast.tree.CaseNode.getDataType(CaseNode.java:39) 表示hibernate不知道子查询是什么类型的,所以报错,那我就强制让它知道 所以我改成这样子

select t, case when t.targetType=0 then 
((select a.name from MarketApp a where a.id = t.target )  || '') 
else '' end
 from ThemeComponent t where t.theme.id = 1
空白-键 2014-06-12
  • 打赏
  • 举报
回复
引用 4 楼 defonds 的回复:
我没有看到查询解析器的配置
没配置,用了默认的,hibernate版本是4.2.0.Final
Defonds 2014-06-12
  • 打赏
  • 举报
回复
我没有看到查询解析器的配置
空白-键 2014-06-12
  • 打赏
  • 举报
回复
引用 1 楼 defonds 的回复:
支持的。hibernate 的测试用例里有:

// $Id: ASTParserLoadingTest.java 9531 2006-03-02 03:14:31Z steve.ebersole@jboss.com $
package org.hibernate.test.hql;

public class ASTParserLoadingTest extends TestCase {

	public ASTParserLoadingTest(String name) {
		super( name );
	}

	public void testSelectClauseCase() {
		Session s = openSession();
		Transaction t = s.beginTransaction();
		Human h = new Human();
		h.setBodyWeight( (float) 74.0 );
		h.setHeight(120.5);
		h.setDescription("Me");
		h.setName( new Name("Gavin", 'A', "King") );
		h.setNickName("Oney");
		s.persist(h);
		String name = (String) s.createQuery("select case nickName when 'Oney' then 'gavin' when 'Turin' then 'christian' else nickName end from Human").uniqueResult();
		assertEquals(name, "gavin");
		String result = (String) s.createQuery("select case when bodyWeight > 100 then 'fat' else 'skinny' end from Human").uniqueResult();
		assertEquals(result, "skinny");
		s.delete(h);
		t.commit();
		s.close();
	}
}

估计是你的配置文件没配好。 贴一下大家帮你看看。
配置如下

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect.mysql}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
			</props>
        </property>

hibernate.dialect.mysql=org.hibernate.dialect.MySQLDialect
我看你这个给出的例子,case when then中并没有用到子查询,如果没用到子查询的话,是没问题的,用到就报错
空白-键 2014-06-12
  • 打赏
  • 举报
回复
引用 楼主 linminqin 的回复:
如下语句报错

select t, case when t.targetType=0 then 
(select a.name from MarketApp a where a.id = t.target )  else '' end
 from ThemeComponent t where t.theme.id = 1
jsp页面报如下错

java.lang.NullPointerException
	at org.hibernate.hql.internal.ast.tree.CaseNode.getDataType(CaseNode.java:39)
	at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:152)
	at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:859)
	at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:649)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:663)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
	at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:105)
	at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:80)
	at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
	at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221)
	at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199)
	at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1777)
后台报如下错

[2014-06-12 09:29:37 ERROR] [http-8080-3] org.hibernate.hql.internal.ast.ErrorCounter.reportError(50) | <AST>:0:0: unexpected AST node: query
<AST>:0:0: unexpected AST node: query
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1363)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.caseExpr(HqlSqlBaseWalker.java:5074)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.arithmeticExpr(HqlSqlBaseWalker.java:3199)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2332)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2145)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1451)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:571)
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
如果去掉子查询,比如改为如下就不会有问题

select t, case when t.targetType=0
 then t.name  else '' end
 from ThemeComponent t where t.theme.id = 1
配置文件如下

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect.mysql}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
			</props>
        </property>

hibernate.dialect.mysql=org.hibernate.dialect.MySQLDialect
我看你这个给出的例子,case when then中并没有用到子查询,如果没用到子查询的话,是没问题的,用到就报错
Defonds 2014-06-12
  • 打赏
  • 举报
回复
支持的。hibernate 的测试用例里有:

// $Id: ASTParserLoadingTest.java 9531 2006-03-02 03:14:31Z steve.ebersole@jboss.com $
package org.hibernate.test.hql;

public class ASTParserLoadingTest extends TestCase {

	public ASTParserLoadingTest(String name) {
		super( name );
	}

	public void testSelectClauseCase() {
		Session s = openSession();
		Transaction t = s.beginTransaction();
		Human h = new Human();
		h.setBodyWeight( (float) 74.0 );
		h.setHeight(120.5);
		h.setDescription("Me");
		h.setName( new Name("Gavin", 'A', "King") );
		h.setNickName("Oney");
		s.persist(h);
		String name = (String) s.createQuery("select case nickName when 'Oney' then 'gavin' when 'Turin' then 'christian' else nickName end from Human").uniqueResult();
		assertEquals(name, "gavin");
		String result = (String) s.createQuery("select case when bodyWeight > 100 then 'fat' else 'skinny' end from Human").uniqueResult();
		assertEquals(result, "skinny");
		s.delete(h);
		t.commit();
		s.close();
	}
}

估计是你的配置文件没配好。 贴一下大家帮你看看。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧