简体   繁体   中英

JPQL (Hibernate 4.3.6) subselect query not working

I have a problem where I can easily perform two separate Queries; the first to get a Set of IDs, and the second to use those ids in an "IN" clause; but when I try to combine the two into one Query with a subselect, it does not work.

This works:

public List<Lead> findLeadsBySupplierAndStatus(List<Integer> supplierIds, StatusCode status){

    Query query = entityManager.createQuery("select ss.id from StateSupplier ss where ss.supplier.id in :supplierIds");
    query.setParameter("supplierIds", supplierIds);

    @SuppressWarnings("unchecked")
    List<Integer> result = (List<Integer>)query.getResultList();

    Query query2 = entityManager.createQuery("from Lead l where l.stateSupplier.id in :ids and l.leadStatus.id= :statusId");
    query2.setParameter("ids", result);
    query2.setParameter("statusId", status.getDbId());

    @SuppressWarnings("unchecked")
    List<Lead> result2 = (List<Lead>)query2.getResultList();
    return result2;
}

but this does not:

public List<Lead> findLeadsBySupplierAndStatus(List<Integer> supplierIds, StatusCode status){
    Query query = entityManager.createQuery("select l from Lead l where l.stateSupplier.id in (select ss.id from StateSupplier ss where ss.supplier.id in :supplierIds) and l.leadStatus.id= :statusId");
    query.setParameter("supplierIds", supplierIds);
    query.setParameter("statusId", status.getDbId());

    @SuppressWarnings("unchecked")
    List<Lead> result2 = (List<Lead>)query.getResultList();
    return result2;
}

I get the following exception:

[20 Mar 2015 17:26:28] [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] 72277  ERROR (org.hibernate.hql.internal.ast.ErrorCounter:73) :: line 1:183: unexpected token: ,
antlr.NoViableAltException: unexpected token: ,
at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:772) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.union(HqlBaseParser.java:1021) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.subQuery(HqlBaseParser.java:3857) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.compoundExpr(HqlBaseParser.java:3226) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.inList(HqlBaseParser.java:3020) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.relationalExpression(HqlBaseParser.java:2866) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.equalityExpression(HqlBaseParser.java:2591) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.negatedExpression(HqlBaseParser.java:2555) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalAndExpression(HqlBaseParser.java:2471) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalOrExpression(HqlBaseParser.java:2436) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.expression(HqlBaseParser.java:2146) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalExpression(HqlBaseParser.java:1922) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.whereClause(HqlBaseParser.java:481) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:737) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:323) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:186) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:295) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:203) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:126) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1254) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) [hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) [hibernate-entitymanager-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) [hibernate-entitymanager-4.3.6.Final.jar:4.3.6.Final]
at com.chooseenergy.core.repository.LeadRepository.findLeadsBySupplierAndStatus(LeadRepository.java:158) [LeadRepository.class:?]
at com.chooseenergy.core.repository.LeadRepository$$FastClassBySpringCGLIB$$6d88acfd.invoke(<generated>) [spring-core-4.0.6.RELEASE.jar:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [spring-core-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640) [spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at com.chooseenergy.core.repository.LeadRepository$$EnhancerBySpringCGLIB$$74954aee.findLeadsBySupplierAndStatus(<generated>) [spring-core-4.0.6.RELEASE.jar:?]
at com.chooseenergy.hermes.quartz.SupplierFTPDispatchJob.dispatch(SupplierFTPDispatchJob.java:71) [SupplierFTPDispatchJob.class:?]
at com.chooseenergy.hermes.quartz.SupplierFTPDispatchJob$$FastClassBySpringCGLIB$$c96ba89a.invoke(<generated>) [spring-core-4.0.6.RELEASE.jar:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [spring-core-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708) [spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) [spring-tx-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) [spring-tx-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) [spring-tx-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) [spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at com.chooseenergy.hermes.quartz.SupplierFTPDispatchJob$$EnhancerBySpringCGLIB$$383c0773.dispatch(<generated>) [spring-core-4.0.6.RELEASE.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_51]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_51]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_51]
at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_51]
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269) [spring-core-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:322) [spring-context-support-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:112) [spring-context-support-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [quartz-2.1.6.jar:?]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-2.1.6.jar:?]

Is there a way to make the single Query work with just JPA classes (EntityManager, Query, etc.)?

Each Lead has an FK (@ManyToOne) to a StateSupplier (stateSupplier) and a an FK (@ManyToOne) to a LeadStatus (leadStatus), and each StateSupplier has an FK (@ManyToOne) to a Supplier (supplier). I think the model is simple enough to not require source code for the Entities, as the problem is just to combine the queries, which work separately.

Why don't you just use join (explicit or implicit) in your query instead of subquery

select l from lead l inner join l.stateSupplier ss 
where ss.supplier.id in :suppllierIds and l.leadStatus.id =:statusId

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM