在 hql 查询的结果中没有得到列名

Posted

技术标签:

【中文标题】在 hql 查询的结果中没有得到列名【英文标题】:Not getting column names in the result of hql query 【发布时间】:2015-11-25 10:14:08 【问题描述】:

我在 Spring Boot 中使用 hql 查询从数据库表中获取记录。我正在使用@ResponseBody 在 json 对象中返回结果。我只得到数据但没有得到列名,所以我无法理解哪个列包含哪些数据。

这是我的DAO

@Transactional
public interface MyDaoInterface extends CrudRepository<Rating, Long>

@Query(countByPostId)
List<Rating> countByPostId(Long post_id);

final String countByPostId= "select new netgloo.models.CountAndPoints(count(r.id), r.points)) from Rating r where r.postId = ?1 group by r.points";


这是我的控制器

  @RequestMapping(value = "/rating/id", produces="application/json")
  @ResponseBody 
  public List<Rating> getRatingInfo(@PathVariable("id") long id,    HttpServletRequest req, HttpServletResponse res) throws Exception 

  List<Rating> postobj = myDao.countByPostId(id);
  return postobj;
  

获取类似的数据

[

"count": 3,
"points": 1
,

"count": 2,
"points": 2
,

"count": 4,
"points": 3

]

但我想喜欢

"result:"[

"count": 3,
"points": 1
,

"count": 2,
"points": 2
,

"count": 4,
"points": 3

]

新类CountAndPoints

package netgloo.models;

public class CountAndPoints 

private long count;

private long points;

public long getCount() 
    return count;


public void setCount(long count) 
    this.count = count;


public long getPoints() 
    return points;


public void setPoints(long points) 
    this.points = points;



例外

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private netgloo.models.MyDaoInterface netgloo.controllers.MainController.myDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDaoInterface': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List netgloo.models.MyDaoInterface.countByPostId(java.lang.Long)!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at netgloo.Application.main(Application.java:25)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private netgloo.models.MyDaoInterface netgloo.controllers.MainController.myDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDaoInterface': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List netgloo.models.MyDaoInterface.countByPostId(java.lang.Long)!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 16 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDaoInterface': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List netgloo.models.MyDaoInterface.countByPostId(java.lang.Long)!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 18 more
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List netgloo.models.MyDaoInterface.countByPostId(java.lang.Long)!
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92)
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:62)
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:72)
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:53)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:135)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:203)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:72)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:349)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:187)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
... 28 more
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree [select new netgloo.models.CountAndPoints(count(r.id), r.points)) from netgloo.models.Rating r where r.postId = ?1 group by r.points]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
at com.sun.proxy.$Proxy63.createQuery(Unknown Source)
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86)
... 41 more
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree [select new netgloo.models.CountAndPoints(count(r.id), r.points)) from netgloo.models.Rating r where r.postId = ?1 group by r.points]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:91)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:109)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:284)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328)
... 48 more

【问题讨论】:

【参考方案1】:
@Query(countByPostId)
List<Rating> countByPostId(Long post_id);

final String countByPostId= "select count(r.id), r.points from Rating r where r.postId=?1 group by r.points";

这没有多大意义。您的查询不会返回 Rating 实例的列表。它返回一个 Object 数组列表,其中每个数组包含 2 个元素:计数和点数。

Rating 类甚至没有包含计数的字段。

您需要一些包含这两个字段的类,以及一个返回此类实例的查询:

select new com.foo.bar.CountAndPoints(count(r.id), r.points) from Rating r where r.postId = ?1 group by r.points"

【讨论】:

感谢您的回复,但收到此异常... java.lang.IllegalArgumentException: Validation failed for query for public abstract java.util.List netgloo.models.MyDaoInterface.countByPostId(java.lang.长)! 如果您需要帮助,您必须编辑您的问题,显示新查询,显示您定义的类,并显示异常的完整堆栈跟踪。 我需要创建新的类 CountAndPoints 吗? 您需要一个将计数和点作为参数的公共构造函数,因为这就是查询所调用的。在r.points 之后你有两个括号而不是一个 是的,谢谢。但是我可以给正在返回的列表命名吗?因为我只得到变量名。【参考方案2】:

在这种情况下,Spring 会为您生成查询。请改用此代码:

@Transactional
public interface MyDaoInterface extends CrudRepository<Rating, Long>
  List<Rating> findByPostId(Long post_id);

有关完整答案,请参阅 JB Nizet 的回答。

【讨论】:

以上是关于在 hql 查询的结果中没有得到列名的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 2008 中将行切换到列,反之亦然

HTTP 状态 500 - 节点没有数据类型:org.hibernate.hql.internal.ast.tree.IdentNode

从行到列的 SQL 结果

MySQL concat() 创建要在查询中使用的列名?

python 得到 postgres 查询结果 可以有列名

如何在java中用hql或sql查询得到某表的所有字段名?