Open cdalexndr opened 4 years ago
Hi @cdalexndr ! I'm not sure I understand fully, isn't that already the case? See https://github.com/darrachequesne/spring-data-jpa-datatables/blob/61ba124db6bd6c5370cd0861dff330d9a40de726/src/main/java/org/springframework/data/jpa/datatables/repository/DataTablesRepositoryImpl.java#L16-L17
I think the two configurations are only needed if you want that only some repositories receive the DataTablesRepositoryImpl
implementation.
In any case, PR is welcome!
Using this repository impl require overwriting the default repository factory bean to DataTablesRepositoryFactoryBean:
@EnableJpaRepositories(repositoryFactoryBeanClass = DataTablesRepositoryFactoryBean.class)
Without this, the following repository:
interface SurveyRepository extends JpaRepository<Survey, Integer>, DataTablesRepository<Survey, Integer> {
...
}
```
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:145)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:63)
at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:348)
at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:302)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:176)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:122)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.testng.TestRunner.privateRun(TestRunner.java:766)
at org.testng.TestRunner.run(TestRunner.java:587)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
at org.testng.SuiteRunner.run(SuiteRunner.java:286)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
at org.testng.TestNG.runSuites(TestNG.java:1039)
at org.testng.TestNG.run(TestNG.java:1007)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'surveyService': Unsatisfied dependency expressed through field 'surveyRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'surveyRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.jpa.datatables.mapping.DataTablesOutput org.springframework.data.jpa.datatables.repository.DataTablesRepository.findAll(org.springframework.data.jpa.datatables.mapping.DataTablesInput,org.springframework.data.jpa.domain.Specification,org.springframework.data.jpa.domain.Specification,java.util.function.Function)! No property findAll found for type Survey!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1429)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:125)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
... 30 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'surveyRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.jpa.datatables.mapping.DataTablesOutput org.springframework.data.jpa.datatables.repository.DataTablesRepository.findAll(org.springframework.data.jpa.datatables.mapping.DataTablesInput,org.springframework.data.jpa.domain.Specification,org.springframework.data.jpa.domain.Specification,java.util.function.Function)! No property findAll found for type Survey!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1803)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
... 48 common frames omitted
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.jpa.datatables.mapping.DataTablesOutput org.springframework.data.jpa.datatables.repository.DataTablesRepository.findAll(org.springframework.data.jpa.datatables.mapping.DataTablesInput,org.springframework.data.jpa.domain.Specification,org.springframework.data.jpa.domain.Specification,java.util.function.Function)! No property findAll found for type Survey!
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.
Using the DataTablesRepositoryFactoryBean
you are overwriting the base repository class to DataTablesRepositoryImpl
, class that overwrites the default one SimpleJpaRepository
so the base functionality is kept.
This method is restrictive as it doesn't allow to use other base repository class (some in house base repository with project specific imlementation) AND use datables repository, so this is a bad way of registering this repository implementation.
Workaround is to group datatables repositories in packages and use @EnableJpaRepositories(basePackages=...)
to restrict the overwrite, but this has other issues:
@EnableJpaRepositories
. One for datatables repositories and another one for other repositories.basePackages
overlap?Instead of overwriting the base repository class, you should provide a repository fragment that when it's used by a repository will automatically decorate that repository and provide datatables functionality. See https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations
This method doesn't require overwriting the base repository class with @EnableJpaRepositories(repositoryFactoryBeanClass =...)
.
Instead of prodividing separate custom repositories for data table usage(DataTablesRepository), an extension mechanism would be better, like querydsl does (example QuerydslPredicateExecutor).
This also eases configuration, as there will not be required to provide two
@Configuration
instances.