2015-09-05 105 views
0

我在HQL中编写了一个查询,但是,它给了我一个错误。在调查错误时,我意识到Hibernate不允许FROM内的子查询。在Hibernate中编写子查询

我是新来编写查询,因此不知道如何将下面提到的查询转换成将被Hibernate接受的格式。

@Query("FROM (SELECT t, " + 
     "MAX(t.transactionId.versionId) OVER (PARTITION BY t.transactionId.referenceId) AS MAX_VER_ID " + 
     "FROM CurrentTransaction t) ABC " + 
     "where t.transactionId.versionId=MAX_VER_ID") 

我知道SO不是这样的问题的地方,但如果有人能够帮助我转换上面的Hibernate查询,那将是非常好的。

编辑:该错误是,

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileWatcher': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.FileWatcherService com.cprt.rtlistener.controller.FileWatcher.fileWatcher; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileWatcherService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.crud.CurrentTransactionService com.cprt.rtlistener.service.FileWatcherService.currentTransactionService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:724) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.FileWatcherService com.cprt.rtlistener.controller.FileWatcher.fileWatcher; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileWatcherService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.crud.CurrentTransactionService com.cprt.rtlistener.service.FileWatcherService.currentTransactionService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298) 
    ... 23 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileWatcherService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.crud.CurrentTransactionService com.cprt.rtlistener.service.FileWatcherService.currentTransactionService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494) 
    ... 25 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.service.crud.CurrentTransactionService com.cprt.rtlistener.service.FileWatcherService.currentTransactionService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298) 
    ... 36 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494) 
    ... 38 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cprt.rtlistener.repository.CurrentTransactionRepository com.cprt.rtlistener.service.crud.CurrentTransactionService.currentTransactionsRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298) 
    ... 49 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'currentTransactionRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494) 
    ... 51 more 
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.cprt.rtlistener.repository.CurrentTransactionRepository.searchAsIWish()! 
    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:136) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:204) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:347) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185) 
    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:1613) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550) 
    ... 61 more 
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: (near line 1, column 6 [FROM (SELECT t,MAX(t.transactionId.versionId) OVER (PARTITION BY t.transactionId.referenceId) AS MAX_VER_ID FROM com.cprt.rtlistener.entity.CurrentTransaction t) ABC where t.transactionId.versionId=MAX_VER_ID] 
    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:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) 
    at com.sun.proxy.$Proxy54.createQuery(Unknown Source) 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86) 
    ... 74 more 
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: (near line 1, column 6 [FROM (SELECT t,MAX(t.transactionId.versionId) OVER (PARTITION BY t.transactionId.referenceId) AS MAX_VER_ID FROM com.cprt.rtlistener.entity.CurrentTransaction t) ABC where t.transactionId.versionId=MAX_VER_ID] 
    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.parse(QueryTranslatorImpl.java:304) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:203) 
    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) 
    ... 81 more 

我尝试此查询,但它也返回一个错误,

@Query("select t from CurrentTransaction t JOIN (SELECT t.transactionId.referenceId ,MAX(t.transactionId.versionId) AS MAX_VER FROM CurrentTransaction GROUP BY t.transactionId.referenceId) MAX_VER ON t.t.transactionId.referenceId=MAX_VER.t.transactionId.referenceId AND t.t.transactionId.versionId=MAX_VER.MAX_VER") 
+1

请包括您得到的错误。 –

+0

@MarkRotteveel:我添加了错误。 – Nishit

+0

你不能。 HQL不支持from子句中的子查询,也不支持max上的分区。坚持哟SQL查询。 –

回答

0

您将无法以翻译与窗口实现的逻辑函数到HQL/JPQL。在HQL中,这两种派生表都不可能。

棒SQL和可能使用本机查询兑现所产生的实体:

List<CurrentTransaction> trx = em.createNativeQuery(
    "SELECT t.* " 
+ "FROM (" 
+ " SELECT " 
+ " t,*, " 
+ " MAX(t.transactionId.versionId) " 
+ "  OVER (PARTITION BY t.transactionId.referenceId) AS MAX_VER_ID " 
+ " FROM CurrentTransaction t" 
+ ") t " 
+ "WHERE t.transactionId.versionId = MAX_VER_ID" 
, CurrentTransaction.class) 
.getResultList(); 

注意,当你使用取消引用嵌套的记录,如t.transactionId.versionIdt.transactionId.referenceId的语法在一些ORDBMS存在,我怀疑你一直试图在HQL中表达关系路径。在这种情况下,您将不得不使用JOIN使用经典SQL。