I have two Service classes which implement the same interface
ServiceClass1
#Service
public class ServiceClass1 implements ItemsService{
#Autowired
Class1DaoImpl class1Dao;
#Transactional
public List<Class1> getAllItems() {
return class1Dao.getAllItems();
}
ServiceClass2
#Service
public class ServiceClass2 implements ItemsService{
#Autowired
Class2DaoImpl class2Dao;
#Transactional
public List<Class2> getAllItems() {
return class2Dao.getAllItems();
}
And this is the controller class
#Controller
public class IndexController {
#Autowired
ServiceClass1 serviceClass1;
#Autowired
ServiceClass1 serviceClass2;
............
.....
}
I got this error when the page was requested
java.lang.IllegalArgumentException: Can not set com.package.ServiceClass1 field com.package.IndexController.serviceClass1 to $Proxy25
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
java.lang.reflect.Field.set(Field.java:657)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:500)
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:609)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:623)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:491)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:432)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
javax.servlet.GenericServlet.init(GenericServlet.java:212)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java:662)
I did some google-ing and can't seem to find any solid answer to why am I getting this error?
You need to autowire against the interface type, not the class type, i.e.
#Autowired
ItemsService serviceClass1;
If you have multiple beans that implement ItemsService, then autowiring isn't really appropriate. Consider using #Resource instead:
#Resource(name="serviceClass1")
ItemsService serviceClass1;
#Resource(name="serviceClass2")
ItemsService serviceClass1;
Related
Hi I try to create a tests for my projeto use only real instances but I getting a follow error:
Failed to load ApplicationContext
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:124)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userQueryService': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'br.com.study.reactivecalendar.domain.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
... 86 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'br.com.study.reactivecalendar.domain.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1799)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1355)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 104 more
I know this error is because my test configuration not solved my repository. I want to use web client to ping in my controller
#ActiveProfiles("test")
#ContextConfiguration(classes = {ReactiveCalendarApplication.class, UserMapperImpl.class, UserQueryService.class,
UserService.class, UserRepository.class})
#WebFluxTest({UserController.class, UserRepository.class})
#AutoConfigureDataMongo
#EnableReactiveMongoRepositories
#ExtendWith(SpringExtension.class)
#EnableAutoConfiguration
public class UserControllerInsertTest {
#Autowired
private UserRepository userRepository;
#Autowired
private ApplicationContext applicationContext;
private RequestBuilder<UserSingleResponse> requestBuilder; // this class I create to build requests using WebTestClient
#BeforeEach
void setup(){
requestBuilder = userResponseRequestBuilder(applicationContext, "/users");
}
#Test
void saveTest(){
var request = UserRequestFactoryBot.builder().build();
requestBuilder.withUri(UriBuilder::build)
.withBody(request)
.generateRequestWithSimpleBody()
.doPost()
.isHttpStatusIsCreated()
.assertBody(response -> {
assertThat(response).isNotNull();
assertThat(response).hasNoNullFieldsOrProperties();
assertThat(response.getId()).containsPattern(MONGOID_REGEX);
assertThat(response.getName()).isEqualTo(request.getName());
assertThat(response.getEmail()).isEqualTo(request.getEmail());
});
}
}
to explain about my dependencies:
UserController (#Controller) needs UserMapper, UserService and UserQuery service.
UserService (#Service) needs UserMapper, UserQueryService and UserRepository.
UserQueryService (#Service) needs UserRepository.
UserRepository (#Repository) needs nothing and extends ReactiveMongoRepository
UserMapper needs noting, it is a interface used by mapstruct.
How can I configure my test to solve all dependencies and use all real instances in my test in SpringWebFlux
I solved my problem, follow my configurations:
My test class to verify controller I use a follow annotations
#ActiveProfiles("test")
#ContextConfiguration(classes = {ReactiveCalendarApplication.class, UserMapperImpl.class, UserQueryService.class,
UserService.class, UserRepository.class, EmbeddedMongoDbConfig.class})
#WebFluxTest({UserController.class, UserRepository.class})
#AutoConfigureDataMongo
#ExtendWith({SpringExtension.class})
public class UserControllerDeleteTest {
// my test code
}
My Database Embedded configuration:
#Slf4j
#TestConfiguration
#EnableReactiveMongoRepositories(basePackageClasses = UserRepository.class)
#AllArgsConstructor
public class EmbeddedMongoDbConfig extends AbstractReactiveMongoConfiguration {
private final Environment environment;
#Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
#Override
protected String getDatabaseName() {
return "test";
}
#Bean
ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient(), getDatabaseName());
}
//optinal configuration, I use because I have custom converters
//for to use OffsetDateTime in my project
#Override
public MongoCustomConversions customConversions() {
List<Converter<? ,?>> converters = new ArrayList<>();
converters.add(new DateToOffsetDateTimeConverter());
converters.add(new OffsetDateTimeToDateConverter());
return new MongoCustomConversions(converters);
}
#Bean
DateTimeProvider dateTimeProvider(){
return new OffsetDateTimeProvider();
}
}
and My application-test.yml
spring:
mongodb:
embedded:
version: 4.0.12
data:
mongodb:
port: 27017
host: localhost
database: test
I have been working on a spring boot application where the application works fine. When i tried to introduce the following code
#Component
#Slf4j
#Getter
#Setter
public class EmployeeDbCreateWriter extends JdbcBatchItemWriter<Employee> {
#Autowired
DataSource datasource;
#Override
public void write(List<? extends Employee> employeeList) throws Exception {
.....
....
}
}
i end up with the following error
Caused by: java.lang.IllegalArgumentException: A DataSource or a NamedParameterJdbcTemplate is
required.
at org.springframework.util.Assert.notNull(Assert.java:201)
at
org.springframework.batch.item.database.JdbcBatchItemWriter.afterPropertiesSet
(JdbcBatchItemWriter.java:143)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.
initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
... 57 more
Configure and component scan is given is working fine before introducing the above class
#Configuration
#EnableWebMvc
#EnableJpaRepositories(basePackages =
{"com.emp.repositories","com.emp2.repositories"})
#EnableAsync(proxyTargetClass = true)
#ComponentScan(basePackages = {"com.emp","com.emp2"})
#EntityScan(basePackages = {"com.emp.models","com.emp2.models"})
#EnableCaching
#EnableBatchProcessing
#Slf4j
public class EmpConfig implements WebMvcConfigurer{
Where am I going wrong?
Per what I see in the JdbcBatchItemWriter it requires Datasource or JdbcTemplate to be provided and it is not aware of the autowired datasource in the child class.
You could try something like this and provide datasource manually in the PostConstruct method
#Component
#Slf4j
#Getter
#Setter
public class EmployeeDbCreateWriter extends JdbcBatchItemWriter<Employee> {
#Autowired
DataSource dataSource;
#PostConstruct
public void initialize() {
super.setDataSource(dataSource);
}
....
}
However per #M.Deinum comments is it doubtful that there is a good reasons to extend JdbcBatchItemWriter and that this class was meant to be extended.
I Have an Spring Boot Application (1.5.10.RELEASE) which contains a main (SpringBootApplication) like this:
#SpringBootApplication
#Configuration
#EntityScan(basePackages = { "db.modell", "db.modell.base" })
#ComponentScan(basePackages = { "de.gui.test" })
public class SpringBootConsoleApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
}
and two REST controllers like the following:
#RestController
#RequestMapping("/as")
public class AController {
#Autowired
private ARepository aRepository;
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<A>> getAs() {
return new ResponseEntity<>(orgtFarbeRepository.findAll(), HttpStatus.OK);
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<A> getA(#PathVariable long id) {
A a = ARepository.findOne(id);
if (party != null) {
return new ResponseEntity<>(ARepository.findOne(id), HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
}
}
Furthermore I have a single test like this:
#RunWith(SpringRunner.class)
#WebMvcTest(AController.class)
public class AControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private ARepository ARepository;
#Test
public void firstTest() throws Exception {
A a = new aFarbe();
a.set....
when(ARepository.findAll()).thenReturn(Collections.singleton(a));
mvc.perform(
get("/as")
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
)
.andExpect(status().isOk());
}
}
The repositories look like this:
public interface ARepository extends CrudRepository<A, Long>
{
Collection<A> findAll();
}
public interface BRepository extends CrudRepository<B, Long>
{
Collection<B> findAll();
}
A and B them self are JPA annotated classes. The whole application contains access to a database..
Furthermore I have a Service like this:
#Service
public class XService {
private static final Logger LOGGER = LoggerFactory.getLogger(XService.class);
#Autowired
private ARepository aRepository;
#Autowired
private BRepository bRepository;
...
}
The XService is not used via #Autowire or so (Just need to remove that):
So I try to run the AControllerTest I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
.. .. at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'XService': Unsatisfied dependency
expressed through field 'BRepository'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
.. .. at
org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 26 more Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 44 more
My assumption is that during the test more context is started than it should. The question is how can I prevent that? Which means only to start the context for the AControler and nothing more? I thought that based on the #WebMvcTest(AController.class) it should be limited already which looks like that it was not the case...
The referenced answer does not really answered my question but a in the context a hint gave me the solution. This means in consequence to add the following to my test:
so I have to add #OverrideAutoConfiguration(enabled=true):
#RunWith(SpringRunner.class)
#WebMvcTest(OrgtFarbenController.class)
#OverrideAutoConfiguration(enabled=true)
public class AControllerTest {
...
}
The persistence API uses JTA managed transactions which is configured in persistence.xml.
EntitymanagerProducer.java
#PersistenceContext( unitName = "PRO" )
EntityManager proEm;
#pro
#Produces
public EntityManager createProEntityManager () {
return this.proEm;
}
The above produced EntityManager could be injected into any #Stateless bean with qualifier #Pro as below,
#Stateless
#Local( OutRepositoryBeanLocal.class )
#Remote( OutRepositoryRemote.class )
#LocalBean
#TransactionAttribute( TransactionAttributeType.MANDATORY )
public class OutRepositoryBean implements OutRepositoryBeanLocal, OutRepositoryRemote {
#Inject
#Pro
private EntityManager entityManager;
#Inject
OutRepository outRepository;
/**
*
*/
#PostConstruct
private void init () {
this.outRepository.setEntityManager( this.entityManager );
}
The above piece of code works seemlessly with no error. But while delegating the job to #Dependent subclasses problem arises,
OutRepository.java
#Dependent
public class OutRepository extends BaseService< Out, Long > {
public OutRepository() {
// TODO Auto-generated constructor stub
}
#Override
protected Class< Out > t () {
return Out.class;
}
public List< Out > getOuts ( Long proId, String Out) {
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder(); <= NPE
CriteriaQuery< Out > criteriaQuery = builder.createQuery( t() );
Root< Out > endPointConfig = criteriaQuery.from( t() );
criteriaQuery.select( endPoint );
TypedQuery< Out > query = this.entityManager.createQuery( criteriaQuery );
return query.getResultList();
}
Whereas the BaseService.java is an abstract class containing generic crud methods.
BaseService.java
#Dependent
public abstract class BaseService< T, I extends Serializable > implements BaseEntity< T, I > {
protected abstract Class< T > t ();
#PostConstruct
protected abstract void init ();
public PersistenceUnitUtil persistenceUnitUtil;
public EntityManager entityManager;
#TransactionAttribute( TransactionAttributeType.MANDATORY )
#Override
public T save ( T t ) {
this.entityManager.persist( t );
return t;
}
While outRepsitory.save() is called there is no problem in transaction everything works great. Yet while outRepository.getOuts(Long proId,String Out), Following exception occurs
[2/7/18 18:19:36:187 IST] 0000003d BusinessExcep E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getOuts" on bean "BeanId(pro-ear#pro-web-0.0.1-SNAPSHOT.war#OutRepositoryBean, null)". Exception data: java.lang.NullPointerException
at org.apache.openjpa.persistence.meta.MetamodelImpl.populate(MetamodelImpl.java:321)
at org.apache.openjpa.persistence.meta.MetamodelImpl.instantiate(MetamodelImpl.java:255)
at org.apache.openjpa.persistence.meta.MetamodelImpl.find(MetamodelImpl.java:224)
at org.apache.openjpa.persistence.meta.MetamodelImpl.<init>(MetamodelImpl.java:89)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:346)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.getCriteriaBuilder(EntityManagerFactoryImpl.java:333)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:1649)
at org.apache.openjpa.persistence.EntityManagerImpl.getCriteriaBuilder(EntityManagerImpl.java:101)
at com.ibm.ws.jpa.management.JPAExEmInvocation.getCriteriaBuilder(JPAExEmInvocation.java:394)
at com.ibm.ws.jpa.management.JPAEntityManager.getCriteriaBuilder(JPAEntityManager.java:494)
at com.org.uck.pro.db.out.control.OutRepository.getOuts(OutRepository.java:68)
at com.org.uck.pro.db.out.control.OutRepositoryBean.getOuts(OutRepositoryBean.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.EJSContainer.invokeProceed(EJSContainer.java:6207)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:568)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callInterceptorsAndDecorators(OpenWebBeansEjbInterceptor.java:528)
at org.apache.webbeans.ejb.common.interceptor.OpenWebBeansEjbInterceptor.callToOwbInterceptors(OpenWebBeansEjbInterceptor.java:200)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at org.apache.webbeans.ejb.WSEJBInterceptor.callToOwbInterceptors(WSEJBInterceptor.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:227)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:548)
at com.ibm.ejs.container.interceptors.InvocationContextImpl.doAroundInvoke(InvocationContextImpl.java:229)
at com.ibm.ejs.container.EJSContainer.invoke(EJSContainer.java:6098)
at com.org.uck.pro.db.out.boundary.EJSLocal1SLOutRepositoryBean_03076fb6.getOuts(EJSLocal1SLOutRepositoryBean_03076fb6.java)
at com.org.uck.pro.ejb.outs.control.OutBean.getOuts(OutBean.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
NullPointerException on CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();, Tried calling the entitymanager using super.entitymanger still the same error persists.
--
Thanks.
There is no Inject annotation in BaseService
Should be like you have it done in OutRepositoryBean
#Inject #Pro
public EntityManager entityManager;
Im using Spring Social in my application:
<spring.framework.version>3.2.0.RELEASE</spring.framework.version>
<hibernate.version>4.1.9.Final</hibernate.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<org.springframework.social-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social-version>
<org.springframework.social.facebook-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social.facebook-version>
<org.springframework-version>3.2.1.RELEASE</org.springframework-version>
<org.springframework.security.crypto-version>3.1.3.RELEASE</org.springframework.security.crypto-version>
When I apply
private final Facebook facebook;
#Inject
public SearchController(Facebook facebook) {
this.facebook = facebook;
}
To my HomeController:
#Controller
public class HomeController {
private final Facebook facebook;
#Inject
public HomeController(Facebook facebook) {
this.facebook = facebook;
}
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
return "home";
}
}
The injection works like intented and I can get information from facebook. However, when I apply it to one of my other Cotrollers like this one
#Controller
#Transactional
#RequestMapping(value = "/search")
public class SearchController {
private static final Logger logger = LoggerFactory.getLogger(SearchController.class);
private final Facebook facebook;
#Inject
public SearchController(Facebook facebook) {
this.facebook = facebook;
}
#PersistenceContext
private EntityManager entityManager;
...
I getting this error:
mar 05, 2013 12:46:36 EM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/project] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchController' defined in file [C:\Users\Nilsi\Downloads\springsource\vfabric-tc-server-developer-2.7.2.RELEASE\base-instance\wtpwebapps\course_info\WEB-INF\classes\com\courseinfo\project\controller\SearchController.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.courseinfo.project.controller.SearchController]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given] with root cause
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:412)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1492)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
at org.springframework.web.method.HandlerMethod.createWithResolvedBean(HandlerMethod.java:202)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:233)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297)
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091)
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
My guess is that I can't inject facebook to a Controller with annotation #Transactional?
CGlib has one important restriction: the target class must provide a default constructor.
If you use property-based injection instead of constructor-based injection, the problem will go away.
I just created an empty default constructor to deal with this.
If you are using Lombok in your code, then you can just add the following annotation to get rid of this error:
#NoArgsConstructor
public class SearchController {