Application Context is failing to load, as it is not finding any qualifying bean of type EntityManager - spring

While running JUnits, ApplicationContext is not loaded, as it could not find a qualifying bean javax.persistence.EntityManager. However, the application for which the Junit is being written is working. Both the application and JUnits are using the same spring configuration.
My Configuration class looks like below
#Configuration
#EnableTransactionManagement
public class AppConfiguration {
#Autowired private EntityManager entityManager;
#Override #Bean
public CustomRepository<Person> customRepository(){
return new CustomRepository<>(Person.class, entityManager);
}
As you see, I'm able to autowire EntityManager, even though I have not explicitly defined the bean and the application is working without any issues.
Now in my JUnit
#RunWith(SpringRunner.class)
#ContextConfiguration(classes=AppConfiguration.class)
#TestPropertySource(locations = "classpath:application.properties")
public class ControllerTest {
#Autowired
private CController controller;
As you see both application and my Junit are using same configuration. How ever when running JUnit, I'm seeing
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I could not understand what in the JUnit is causing the isssue, while the aplication is still working.
Thanks

it clearly means that EntityManager bean is not defined in your application context.
So either you define it by yourself or let Spring-boot do the lifting(Spring-boot auto config your context based on dependencies in your POM file). If you choose the latter option then one option to get rid of the error by adding H2 DB.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
UPDATE:
In your test, instead of initializing your context using #ContextConfiguration do that with #SpringBootTest it will bootstrap your entire container(including other beans that are not defined in AppConfiguration.java). Read more about in spring-docs

Related

How to autowire a spring DAO repository in its unit test?

I am experimenting Spring's reactive support for DB operations. So I have created a repository as:
public interface FeatureRepository extends ReactiveCrudRepository<Feature, UUID> {}
Now I want to test it through a unit test.
So my test is:
#ExtendWith(SpringExtension.class)
#SpringBootTest
public class FeatureRepositoryTest {
#Autowired
FeatureRepository featureRepository;
.....
}
But I get error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of
type 'x.y.z.FeatureRepository' available: expected at least 1 bean which
qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
How can I solve this issue?
Your DAO is managed as any other tested class, so without defining a specific ApplicationContext in your test runtime, Spring do nothing and the FeatureRepository bean is not known.
2 approaches :
Your test is more about integration test, so your test runtime need to be specify.
Your test is more about unit test, I suggest you to mock your repository (pragrammatically or using framework like Mockito)
Regards.

NoSuchBeanDefinitionException for bean defined in JavaConfig

I was using XML configuration on my project earlier, and everything was working.
We're moving gradually to java config, so right now I'm at a stage where I'm using a mix of Java and XML configs.
Here's the problem, there is a bean defined in my XML config : beanA.
<bean id="beanA" class="BeanA" />
The class BeanA has an autowired dependency on BeanB.
class BeanA {
#Autowired
BeanB beanB;
}
Earlier, this beanB was also in XML config, and it ran correctly.
Now, I have made this change, and it is no longer working :
#Configuration
class MyConfig {
#Bean
public BeanB beanB() {
return new BeanB();
}
}
Apart from adding #Configuration and #Bean annotations, is there something else required to do that I am missing?
I'm getting the following error :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB': Unsatisfied dependency expressed through field 'beanA';
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxxxxx.yyy.zzzzzzzzzzzz.abc.beanA' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Please note,
I have only moved beanB to be created via java config.
BeanA actually has more dependencies, so I cannot move it to java config at this stage (will be doing proper migration later).
you need to add configuration for BeanB as well in the xml configuration. as when the program is run it loads all the bean definition from xml configuration file. So it looks like BeanB definition is missing in configuraion file.
Spring does not load the beans from the classes annotated with #Configuration unless it has been told to look for classes with this annotation.
To make spring look for these classes, the following must be added in your xml configuration :
<context:component-scan base-package="com.xxxxx.yyy.zzzz">
It will then recursively find and initialize all the beans in the package com.xxxxx.yyy.zzzz.

Spring Boot - Autowiring a DataSource Bean

I have a basic Spring Boot application annotated like this:
#SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
I have the following entries in my application.properties file:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/db
spring.datasource.username=dbuser
spring.datasource.password=dbpassword
From my understanding Spring Boot should be able to automatically autowire a DataSource Bean from these properties.
However if I try:
#Autowired
DataSource dataSource;
anywhere in my application (f.i. in #Configuration files), I get the following error in IntelliJ:
"Could not autowire. No beans of 'DataSource' type found."
Is there something obvious that I'm missing for this to work?
I have a single DataSource.
The bean actually does get initialized correctly. This is possibly just an IntelliJ tooltip bug.
Adding #SuppressWarnings to hide the message will work without further issues.
Intelij apparently even in the 2016.2 still does not support the #SpringBootApplication annotation. You either have to remove the #SpringBootApplication annotation and replace it with the #Configuration, #EnableAutoConfiguration and #ComponentScan annotations or just ignore the errors.

Disabling Transaction Management in Spring JMS listener

I have a spring boot application as a Spring JMS listener. i have configured multiple datasource manager one for Oracle and another one for DB2 .
whenever i am starting app ,jms listener container is looking for a transaction manager bean and giving below error as it find two bean.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jms.JmsAnnotationDrivenConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.transaction.PlatformTransactionManager org.springframework.boot.autoconfigure.jms.JmsAnnotationDrivenConfiguration.transactionManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: db2TransactionManager,oracleTransactionManager
i dont want to maintain JMS transaction. how could i achieve it or how can we disable jms transaction feature?
below are the annotation i have added on my main spring boot class. also i am using Spring Data repository
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class})
#ComponentScan(basePackages = "com.deere.oracledataupdate.*")
//#EnableJpaRepositories(basePackages ="com.deere.oracledataupdate.dao.springdata")
#EntityScan(basePackages = "com.deere.oracledataupdate.*")
#PropertySource({ "classpath:application-${IafConfigSuffix}.properties" })
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Looking to the current Spring Boot code we have (JmsAnnotationDrivenConfiguration):
#Autowired(required = false)
private JtaTransactionManager transactionManager;
So, right now it requires only the bean which is exactly JtaTransactionManager by type. I guess both yours are DataSourceTransactionManager.
I'm sure that was correct fix to worry only about the XA tx-manager for auto-config.
Seems for me you can fix your issue with something like #Primary on one of your tx-manager beans.
But... Do you need a JMS Annotation support in your application at all?
Maybe it would be just enough to exclude JmsAnnotationDrivenConfiguration as well?
If need it anyway, I see only one way to fix it: disable JmsAnnotationDrivenConfiguration and configure #EnableJms manually, bypassing the tx-manager issue and just don't configure it for the DefaultJmsListenerContainerFactory as you request.
See JmsAnnotationDrivenConfiguration source code for more information.

JBoss - Autowiring list - #Resource, #Inject throws NoSuchBeanDefinitionException

Env - JBoss 5.1, Spring 3.1.2, jdk 1.5
I am trying to autowire a list. As per the discussion here Auto-wiring a List using util schema gives NoSuchBeanDefinitionException, #Resource doesn't work with JBoss.
<util:list id="reportTypes">
<value>PDF</value>
<value>CSV</value>
<value>XML</value>
</util:list>
#Inject
private List<String> reportTypes;
I also tried using #Inject, but I get the same exception. What am I missing ?
I am using the JSR 330, com.springsource.javax.inject-0.9.0.PFD.jar file for #Inject as mentioned here http://forum.springsource.org/showthread.php?78737-JSR-330-Inject-Spring-3-0
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [java.lang.String] found for dependency
[collection of java.lang.String]: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations: {#javax.inject.Inject()}
EDIT using
#Resource(name = "reportTypes")
private List<String> reportTypes;
throws
java.lang.RuntimeException: mapped-name is required for reportTypes of deployment app.war
at org.jboss.web.tomcat.service.injection.WebResourceHandler.loadXmlResourceEnvRefs(WebResourceHandler.java:287)
at org.jboss.web.tomcat.service.injection.WebResourceHandler.loadXml(WebResourceHandler.java:325)
at org.jboss.web.tomcat.service.TomcatInjectionContainer.processMetadata(TomcatInjectionContainer.java:550)
at org.jboss.web.tomcat.service.WebCtxLoader.start(WebCtxLoader.java:158)
I've battled with this problem a few times myself. I don't have an exact answer to your question, other than the fact that I've moved to using #Inject #Named pairs. That seems to work most of the time.
The reason #Resource doesn't work, to my knowledge, is not the fault of jboss itself, but the fault of the version of tomcat bundled by jboss.

Resources