我在HQL中编写了一个查询,然而,它给了我一个错误。在调查错误时,我意识到Hibernate不允许FROM中的子查询。
我是编写查询的新手,因此不知道如何将下面提到的查询转换为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")
答案 0 :(得分: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();
注意,虽然您在某些ORDBMS中存在用于取消引用t.transactionId.versionId
或t.transactionId.referenceId
等嵌套记录的语法,但我怀疑您一直试图表达关系HQL中的路径。在这种情况下,您必须使用JOIN来使用经典SQL。