2015-09-25 2 views
0

Я работаю с JPA2, и я ищу, чтобы написать поисковый запрос, который моделирует этот запрос sqlJPA Критерии поиска для многих-многих отношений

выбрать c. , т. из кампаний c, campaign_tags ct, теги t, где c.id = ct.campaign_id и t.id = ct.tag_id и t.name in ('buzz', 'blitzy');

Вот классы

class campaign { 
     @ManyToMany(cascade = {CascadeType.ALL}) 
     @JoinTable(name = "campaign_tags", 
     joinColumns = @JoinColumn(name = "campaign_id"), 
     inverseJoinColumns = @JoinColumn(name = "tag_id") 
    ) 
     private Set<Tag> tags; 
    } 

    class Tag{ 
     @Id 
     private String id; 

     @Column 
     private String name; 
    } 

Я использую критерии строитель писать Предикаты и спецификации, так что я могу использовать его для поиска через JPA Resository .. Следующий код не работает.

public static Specification<Campaign> hasTags(String searchTerm) { 
    return (root, query, cb) -> { 
     //searchTerm contacts tagNames represented as comma separated strings 
     List<String> list = new ArrayList<String>(Arrays.asList(searchTerm.split(","))); 

     CriteriaQuery<Tag> cq = cb.createQuery(Tag.class); 
     Root<Campaign> rootAnswer = cq.from(Campaign.class); 
     Join<Tag,Campaign> joinAnswerCollaborator = rootAnswer.join("tags"); 
     return joinAnswerCollaborator.in(list); 

    }; 
    } 

Я получаю ошибку:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'generatedAlias1' in 'where clause' 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) 
at com.mysql.jdbc.Util.getInstance(Util.java:372) 
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:980) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3835) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3771) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2535) 
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1911) 
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2034) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82) 
at org.hibernate.loader.Loader.getResultSet(Loader.java:2066) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839) 
at org.hibernate.loader.Loader.doQuery(Loader.java:910) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) 
at org.hibernate.loader.Loader.doList(Loader.java:2554) 
at org.hibernate.loader.Loader.doList(Loader.java:2540) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) 
at org.hibernate.loader.Loader.list(Loader.java:2365) 
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) 
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) 
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300) 
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) 
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) 
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) 
at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:67) 
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:387) 
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:497) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:436) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:421) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:393) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:506) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 
at com.sun.proxy.$Proxy88.findAll(Unknown Source) 
at com.irispr.controllers.SearchController.searchCampaigns(SearchController.java:98) 
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:497) 
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

ответ

1

Ваша спецификация должна выглядеть следующим образом:

new Specification<Campaign>() { 
     @Override 
     public Predicate toPredicate(Root<Campaign> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { 
      List<String> list = new ArrayList<>(Arrays.asList(searchTerm.split(","))); 
      Join join = root.join("tags"); 
      return join.get("name").in(list); 
     } 
} 

Вы не должны создавать новые критерии запроса или корень, у вас уже есть передан вам в параметрах метода toPredicate.

+0

Спасибо, Алекс, это сработало !!!! –