web-dev-qa-db-ja.com

「Java.lang.IllegalArgumentException:プロジェクションタイプはインターフェースでなければなりません」エラー

Spring Data JPAにプロジェクションを実装するのが困難です。

2017-10-19 11:31:33.968 ERROR 4272 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Projection type must be an interface!; nested exception is Java.lang.IllegalArgumentException: Projection type must be an interface!] with root cause

Java.lang.IllegalArgumentException: Projection type must be an interface!
    at org.springframework.util.Assert.isTrue(Assert.Java:92) ~[spring-core-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.data.projection.ProxyProjectionFactory.createProjection(ProxyProjectionFactory.Java:110) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.data.projection.SpelAwareProxyProjectionFactory.createProjection(SpelAwareProxyProjectionFactory.Java:42) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.lambda$readPageWithProjection$1(JpaSpecificationExecutorWithProjectionImpl.Java:77) ~[specification-with-projections-1.0.5.jar:1.0.5]
    at org.springframework.data.domain.Chunk.getConvertedContent(Chunk.Java:168) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.data.domain.PageImpl.map(PageImpl.Java:104) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.readPageWithProjection(JpaSpecificationExecutorWithProjectionImpl.Java:77) ~[specification-with-projections-1.0.5.jar:1.0.5]
    at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.findAll(JpaSpecificationExecutorWithProjectionImpl.Java:49) ~[specification-with-projections-1.0.5.jar:1.0.5]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_131]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_131]
    at Java.lang.reflect.Method.invoke(Method.Java:498) ~[na:1.8.0_131]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.Java:504) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.Java:489) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.Java:461) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.Java:56) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.Java:99) ~[spring-tx-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.Java:282) ~[spring-tx-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.Java:96) ~[spring-tx-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.Java:136) ~[spring-tx-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.Java:133) ~[spring-data-jpa-1.11.7.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.Java:92) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.Java:57) ~[spring-data-commons-1.13.7.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:213) ~[spring-aop-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at com.Sun.proxy.$Proxy90.findAll(Unknown Source) ~[na:na]
    at com.lbs.data.demo.topic.TopicService.getAllSimpleTopics(TopicService.Java:68) ~[classes/:na]
    at com.lbs.data.demo.topic.TopicController.getAllSimpleTopics(TopicController.Java:23) ~[classes/:na]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_131]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_131]
    at Java.lang.reflect.Method.invoke(Method.Java:498) ~[na:1.8.0_131]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:205) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:133) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:97) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:827) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:738) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:967) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:901) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:970) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:861) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:635) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:846) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:742) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:231) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52) ~[Tomcat-embed-websocket-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.Java:99) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.Java:108) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:81) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.Java:197) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:193) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:166) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:198) ~[Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:96) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:478) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:140) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:80) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:87) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:342) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.coyote.http11.Http11Processor.service(Http11Processor.Java:799) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.Java:66) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.Java:868) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.Java:1457) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.Apache.Tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.Java:49) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142) [na:1.8.0_131]
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617) [na:1.8.0_131]
    at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61) [Tomcat-embed-core-8.5.20.jar:8.5.20]
    at Java.lang.Thread.run(Thread.Java:748) [na:1.8.0_131]

私の投影クラスは:

@Projection(name="topicSimple", types = Topic.class)
public interface TopicSimpleOuter {
        String getId();
        String getName();
}

私のエンティティクラスは:

@Entity
@ProjectionWithSpecification (interfaceClass = "com.lbs.data.demo.topic.TopicRepository.TopicSimple")
public class Topic {
...
}

私のレポクラスは:

@Repository
@RepositoryRestResource(excerptProjection = TopicSimpleOuter.class)
public interface TopicRepository extends JpaRepository<Topic,String>,JpaSpecificationExecutorWithProjection<Topic> {//interface olması ne kadar ilginç

    List<TopicSimpleOuter> findById(String id);

}

Configuration class is:
public class TopicConfiguration extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.getProjectionConfiguration().addProjection(TopicSimpleOuter.class);
    }
}

関連するコントローラーメソッドは次のとおりです。

@RequestMapping(value = "/topicsSimple/{id}/projection=topicSimple", method = RequestMethod.GET)
    public Page<TopicSimpleOuter> getAllSimpleTopics(@PathVariable String id){
        return topicService.getAllSimpleTopics(id);
    }

プロジェクションを適切に追加しましたが、プロジェクションのタイプについてまだ不満があります。

テストクラスを作成して使用する場合も問題ありませんが、postmanを使用すると上記のエラーが発生します。何が欠けていますか?

11
lamostreta

インターフェイスのgetメソッドの戻り値の型がエンティティの型と一致しない場合、このエラーが発生しました。

この場合、String getId();はエンティティ自体のidのタイプと一致しないと思います(投稿されたすべてのコードにはIDのタイプとしてStringがありますが) 、エンティティ自体のコードが欠落しており、問題が私のものと同じである場合、それは一致する必要があるビットです)。

7
Player One

Spring Bootを1.4.1から1.5.13にアップグレードした後、ユニットテストの1つで同じ例外がスローされました

新しいバージョンは私のProjectionインターフェースでのゲッターの順序の点でより厳しいようです。リポジトリにProjectionのリストを返す "SELECT"ステートメントがあります。修正は、Projectionインターフェイスのゲッターメソッドの順序が "SELECT"ステートメントの順序と同じであることを確認することでした。

あなたの問題の原因は私のものと似ているのでしょうか。

5
rmartinus