Autowire not working with controller Spring Boot - spring

Whenever I am trying to autowire a custom repository implementing JPA Repository within my controller class it is unable to do so and throwing a no bean def found error whereas if I am doing the same with any Service Class its working fine. Can anyone please explain to me why is it so?
Spring Boot
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-02-15 13:01:50.169 ERROR 16304 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field customerRepo in Controllers.MainController required a bean of type 'Repository.CustomerRepo' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'Repository.CustomerRepo' in your configuration.
```
#SpringBootApplication
#ComponentScan(basePackages = "Controllers")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
``````````````````
#RestController
#RequestMapping("/")
public class MainController {
#Autowired
private CustomerRepo customerRepo;
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String homePage() {
Customer testCustomer = new Customer();
testCustomer.setFirstName("csdcsdccs");
testCustomer.setLastName("csdcsdccs");
testCustomer.setMiddleName("csdcsdccs");
testCustomer.setAddressLine("csdcsdccs");
testCustomer.setCountry("csdcsdccs");
testCustomer.setPincode(713201);
testCustomer.setState("csdcsdccs");
testCustomer.setDateOfBirth(new Date(2019, 5, 13));
customerRepo.save(testCustomer);
return "inserted";
}
}
`````````````
#Repository
public interface CustomerRepo extends CrudRepository<Customer, Long> {
}
``````````````````````````

Spring application is unable to scan the repository. Could you please check if the repository is defined defined under the base package otherwise add Repository repository package also in #ComponentScan there.
#SpringBootApplication
#ComponentScan(basePackages = {"Controllers","Repository"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

Can you try #Component or #Repository annotations on you Repo?

Related

I am trying to push data into my db using JpaRepository but there was some error stopping me to do so

*************************** APPLICATION FAILED TO START ***************************
Description:
Field userRepository in com.Lex.Exercise.Service.RegistrationService required a bean of type 'com.Lex.Exercise.Repository.UserRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.Lex.Exercise.Repository.UserRepository' in your configuration.
//UserRepository
package com.Lex.Exercise.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.Lex.Exercise.Model.UserEntity;
public interface UserRepository extends JpaRepository<UserEntity, String>{
}
//RegistrationService
#ComponentScan(basePackages = "com.Lex.Exercise.Repository")
#Component
public class RegistrationService {
#Autowired
private UserRepository userRepository;
//business methods and other validations comes here
}
This is the main class
package com.Lex.Exercise.SpringBootDemo;
#SpringBootApplication
#PropertySource(value = { "classpath:configuration.properties" })
public class SpringBootDemoApplication implements CommandLineRunner {
#Autowired
private RegistrationService service;
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
Below is the project structure:
/SpringBootDemo/src/main/java/com/Lex/Exercise/Model/User.java
/SpringBootDemo/src/main/java/com/Lex/Exercise/Model/UserEntity.java
/SpringBootDemo/src/main/java/com/Lex/Exercise/Repository/UserRepository.java
/SpringBootDemo/src/main/java/com/Lex/Exercise/Service/RegistrationService.java
/SpringBootDemo/src/main/java/com/Lex/Exercise/SpringBootDemo/SpringBootDemoApplication.java
/SpringBootDemo/src/main/resources/application.properties
/SpringBootDemo/src/main/resources/configuration.properties
Please help me how I could resolve this
Remove #ComponentScan(scanBasePackages = "com.Lex.Exercise.Repository") on your RegistrationService.class
And your SpringBootDemoApplication.class should look like this. Than your components in subpackages of com.Lex.Exercise will be injected into the Application context.
#SpringBootApplication
#ComponentScan(basePackages = {"com.Lex.Exercise"})
public class SpringBootDemoApplication{
public static void main(String[] args) {
new SpringApplication(SpringBootDemoApplication.class).run(args);
}
}
In general it is a good idea to put the SpringApplication in the top level package (like in your case com.Lex.Exercise) because Spring Boot scans automatically all subpackages of that class. So you wouldn't need the extra #ComponentScan
The #ComponentScan(basePackages = "com.Lex.Exercise.Repository") belongs on your configuration, which might be your application class

Identifying Start-Class during runtime in spring boot

I am trying to identify a way to know the name of the Main-Class that started SpringBoot.
e.g.
#SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
#RestController
public class SampleController
{
#GetMapping("/hello")
pubic String sayHello()
{
System.out.println("Need start class name: "+System.getProperty("sun.java.command"));
return "hello";
}
}
}
When I run the springboot using java -jar myappname.jar ,the System.getProperty("sun.java.command") returns org.springframework.boot.loader.JarLauncher
Can anyone advise, how can I get the name of actual run class. I have tried specifying the start-class attribute in the manifest.mf. It still gave me org.springframework.boot.loader.JarLauncher as the start-class.
You should be able to #Autowire in the ApplicationContext and then do context.getBeansWithAnnotation(SpringBootApplication.class).values().toArray()[0].getClass().getName(), which will give you the first (and presumably only) bean in the context annotated with #SpringBootApplication

Creating Bean inside Spring boot application using command line runner

#SpringBootApplication
public class ReactiveCouchbaseExample1Application {
#Bean
CommandLineRunner employees(ApplicationContext context) {
EmployeeRepository repository = context.getBean(EmployeeRepository.class);
return args -> {
repository
.deleteAll()
.subscribe(null,null,()->{
Stream.of(new Employees(UUID.randomUUID().toString(), "Nikhil", 23, 3000L),
new Employees(UUID.randomUUID().toString(), "Shubham", 23, 3000L),
new Employees(UUID.randomUUID().toString(), "Anshul", 23, 3000L))
.forEach(employee->{
repository.save(employee)
.subscribe(System.out::println);
});
});
};
}
public static void main(String[] args) {
SpringApplication.run(ReactiveCouchbaseExample1Application.class, args);
}
I wants to run this piece of logic as soon my application context get loaded but when i started my app it shows this error.
Method employees in com.reactive.reactivecouchbaseexample1.ReactiveCouchbaseExample1Application required a bean of type 'com.reactive.repository.EmployeeRepository' that could not be found.
Can someone tell me how can I create a repository bean inside CommandLineRunner.
I also googled it but could'nt find any answers.
This is my repository
#Repository
public interface EmployeeRepository extends
ReactiveCouchbaseRepository<Employees, String>{
}
Scanned component must be in the same package as #SpringBootApplication annotated class, or its subpackage. I can only assume it is ReactiveCouchbaseExample1Application.class.
Maybe your repo is in different package, or you didn't enable component scan with #SpringBootApplication or #ComponentScan.

Intellij Spring: NoSuchBeanDefinitionException: No bean named 'accountDAO' available

This is driving me nuts. I have the following files, it is a very simple setup.
public class MainApp {
public static void main(String[] args) {
//read the spring config java class
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("Config.class");
//System.out.println("Bean names: " + Arrays.toString(context.getBeanNamesForType(AccountDAO.class)));
//get the bean from spring container
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
//call the business method
accountDAO.addAccount();
//close the spring context
context.close();
}
}
Config.java:
#Configuration
#ComponentScan("com.aop")
#EnableAspectJAutoProxy
public class Config {
}
LoggingAspectDemo.java:
#Aspect
#Component
public class LoggingAspectDemo {
//this is where we add all our related advices for the logging
//let's start with an #Before advice
#Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("\n=======>>>> Executing #Before advice on method addAccount() <<<<========");
}
}
AccountDAO.java
#Component
public class AccountDAO {
public void addAccount() {
System.out.println(getClass() + ": Doing my Db work: Adding an account");
}
}
Everytime I run the MainApp.java, I get:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'accountDAO' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
All the files are under "com.aop" package so #ComponentScan should be scanning all the components. It looks simple enough but I can't get my hands around the problem, can anyone help me where I am going wrong?
You're invoking the constructor of AnnotationConfigApplicationContext with "Config.class" as String argument, but this constructor is actually for invoking with base packages i.e. the argument must be a package name.
Since you want to use it with the Configuration class, use the constructor which accepts Class instance instead i.e.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

#Profile Spring Annotation in Camel

I have a Spring Boot + Apache Camel project that works brilliantly. I just added a new bean though where I wanted to have its implementation be profile-specific. I created Spring tests to verify it, and it works as expected, but when I run the server I get the following stack trace:
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: MyFancyBean
at org.apache.camel.component.bean.RegistryBean.getBean(RegistryBean.java:94)
at org.apache.camel.model.language.MethodCallExpression.createExpression(MethodCallExpression.java:196)
at org.apache.camel.model.language.MethodCallExpression.createPredicate(MethodCallExpression.java:210)
at org.apache.camel.model.language.ExpressionDefinition.createPredicate(ExpressionDefinition.java:148)
at org.apache.camel.model.ValidateDefinition.createProcessor(ValidateDefinition.java:63)
at org.apache.camel.model.ValidateDefinition.createProcessor(ValidateDefinition.java:35)
at org.apache.camel.model.ProcessorDefinition.makeProcessorImpl(ProcessorDefinition.java:545)
at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:506)
at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:222)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1068)
I have an interface and two implementations:
public interface MyFancyBean { ... }
public class FooFancyBean implements MyFancyBean { ... }
public class NonFooFancyBean implements MyFancyBean { ... }
Depending on profile, the correct bean is read instantiated:
#Configuration
public class AppConfig {
#Bean
#Profile("foo")
MyFancyBean fooBean() {
return new FooFancyBean();
}
#Bean
#Profile("!foo")
MyFancyBean nonFooBean() {
return new NonFooFancyBean();
}
}
I've verified this works a couple of ways. First, a couple tests:
#ActiveProfiles("anything-but-foo")
#RunWith(SpringJUnit4ClassRunner.class)
#ComponentScan(basePackages = {"com.example", "com.jtv.spring.boot"})
#EnableAutoConfiguration
#Component
public class NonFooBean_SpringTest {
#Autowired
private MyFancyBean bean;
#Test
// ... here "bean" is instantiated as "NonFooFancyBean"
So the test works.
Further, when I start my app, depending on profile the correct bean in my #Configuration class above is called.
But Camel is still angry and says "NoSuchBeanException" on startup.
FWIW, here's how I'm referencing the bean:
#Component
public class MyCamelRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
// [...]
from("direct:processStuff").
validate().method("MyFancyBean").
process("MyProcessor");
}
}
How do I get Camel to honor this config?
Whoooo... Y'all get to be my rubber duck today. I just autowired it. (This doesn't work for my processor, which is why it didn't occur to me initially.)
#Component
public class MyCamelRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
// [...]
#Autowired MyFancyBean myFancyBean;
from("direct:processStuff").
validate().method(myFancyBean).
process("MyProcessor");
}
}

Resources