Im new in Spring Boot. I have to connect my app to MySQL servver. At thetime of creating back side of app, I got a problem with beans in Spring. When I try to run this in my server I get the error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.bagyt.reposotories.UniversityRepository' available: expected at least 1 bean which qualifies as an autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
This is my controller class
package com.bagyt.controller;
import com.bagyt.exception.ResourceNotFoundException;
import com.bagyt.model.University;
import com.bagyt.repositories.UniversityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
#RestController
#RequestMapping("/universityApi")
public class UniversityController {
#Autowired
UniversityRepository universityRepository;
#GetMapping("/university")
public List<University> getAllNotes() {
return universityRepository.findAll();
}
#PostMapping("/university")
public University createNote(#Valid #RequestBody University note) {
return universityRepository.save(note);
}
#GetMapping("/university/{id}")
public University getNoteById(#PathVariable(value = "id") Long universityId) {
return universityRepository.findById(universityId)
.orElseThrow(() -> new ResourceNotFoundException("University", "id", universityId));
}
#PutMapping("/university/{id}")
public University updateNote(#PathVariable(value = "id") Long universityId,
#Valid #RequestBody University universityDetails) {
University university = universityRepository.findById(universityId)
.orElseThrow(() -> new ResourceNotFoundException("University", "id", universityId));
university.setName(universityDetails.getName());
university.setEmail(universityDetails.getEmail());
university.setDescription(universityDetails.getDescription());
university.setPhotoLink(university.getPhotoLink());
University updatedNote = universityRepository.save(university);
return updatedNote;
}
#DeleteMapping("/university/{id}")
public ResponseEntity<?> deleteNote(#PathVariable(value = "id") Long universityId) {
University note = universityRepository.findById(universityId)
.orElseThrow(() -> new ResourceNotFoundException("University", "id", universityId));
universityRepository.delete(note);
return ResponseEntity.ok().build();
}
}`
My repository
package com.bagyt.repositories;
import com.bagyt.model.University;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface UniversityRepository extends JpaRepository<University, Long> {
}
I have tested and made sure the error is in my #Autowired line in the controller.
Thanks for any help!
As docs says about #SpringBootApplication
#ComponentScan: enable #Component scan on the package where the application is located
That means Spring will look for beans in your com.bagyt.controller, that is the same package where a class annotated with #SpringBootApplication has been defined and its subpackages.
You should move BagytApplication in com.bagyt package if you want to scan for components in other packages such as com.bagyt.repository.
Check your controller package is either same package or sub package of class with #springBootApplication. If any dependency(#controller,#Service,#Repository) is in different package structure use #componentscan(give package name ).I think it should work.
On springboot main class, you can add
#EnableJpaRepositories(basePackages = "com.bagyt.repositories")
Related
I'm checking out some of Spring Integration with GCP pub sub and I've cloned their sample project. I'm getting a warning / error in my IDE which I'm struggling to understand.
Basically in this class https://github.com/spring-cloud/spring-cloud-gcp/blob/6c95a16f7e6ad95404b4f992b5f46340e831e5cb/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-json-sample/src/main/java/com/example/WebController.java#L47
package com.example;
import java.util.ArrayList;
import java.util.List;
import com.example.SenderConfiguration.PubSubPersonGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;
/**
* Provides REST endpoint allowing you to send JSON payloads to a sample Pub/Sub topic for
* demo.
*
* #author Daniel Zou
*/
#RestController
public class WebController {
private final PubSubPersonGateway pubSubPersonGateway;
#Autowired
#Qualifier("ProcessedPersonsList")
private ArrayList<Person> processedPersonsList;
public WebController(PubSubPersonGateway pubSubPersonGateway, SenderConfiguration.PubSubProjectGateway pubSubProjectGateway ) {
this.pubSubPersonGateway = pubSubPersonGateway;
}
#PostMapping("/createPerson")
public RedirectView createUser(#RequestParam("name") String name, #RequestParam("age") int age) {
Person person = new Person(name, age);
this.pubSubPersonGateway.sendPersonToPubSub(person);
return new RedirectView("/");
}
#GetMapping("/listPersons")
public List<Person> listPersons() {
return this.processedPersonsList;
}
}
I have the following error
Could not autowire. No beans of 'PubSubPersonGateway' type found.
Could someone please explain why I'm getting this error / warning and if its something I need to be concerned with? FYIW, The project will compile and run correctly
This is just an IDE inspection issue, nothing more. That PubSubPersonGateway is a special #MessagingGateway bean which is not understood by IDE. Probably better to raise an improvement ticket against that IDE to let them know that Spring Integration inspection should be improved.
I'm trying to connect my Controller to Repository in one of the spring application but I'm getting an error saying "Field tweetRepository in TweetsController.TweetsController required a bean of type 'TweetsController.TweetRepository' that could not be found."
Can someone help me with this? Thanks in advance. I've attached code samples as well.
TwitterApplication.java
package SpringMVC.Twitter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan("AuthController")
#ComponentScan("TweetsController")
public class TwitterApplication {
public static void main(String[] args) {
SpringApplication.run(TwitterApplication.class, args);
}
}
TwitterController.java
package TweetsController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
#RestController
public class TweetsController {
#Autowired
private TweetRepository tweetRepository;
#RequestMapping("/tweets")
public Iterable<TweetsContent> getAllTweets() {
return tweetRepository.findAll();
}
#RequestMapping("tweet/{id}")
public Optional<TweetsContent> getTweet(#PathVariable int id) {
return tweetRepository.findById(id);
}
#RequestMapping(method = RequestMethod.POST, value = "/tweets")
public boolean addTweet(#RequestBody TweetsContent tweet) {
TweetsContent t = tweetRepository.save(new TweetsContent(tweet.getTitle(), tweet.getContent()));
if (t != null)
return true;
else
return false;
}
}
TwitterRepository.java
package TweetsController;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface TweetRepository extends CrudRepository<TweetsContent, Integer> { }
Add the spring data dependency on your pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Add this too.
#ComponentScan("TweetRepository")
You don't need to use #ComponentScan("AuthController") and #ComponentScan("TweetsController") because if you use #SpringBootApplication, scanning will occur from the package of the class that declares this annotation. But you need to put TwitterApplication like this:
You don't have to specify #ComponentScan in your TwitterApplication, because spring boot application is scanning its own directory at the startup. and remove the #Repository
annotation from your repository class, it is also not needed.
This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 3 years ago.
I am developing a spring boot application to send sms notification. This is my class for the purpose.
package org.otp.services;
import org.otp.Configurations;
import com.mashape.unirest.http.HttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
#Component
public class SmsService
{
private static final Logger LOG = LoggerFactory.getLogger(SmsService.class);
public String send(String mobile, String msg)
{
//Code
}
}
And this is the class which uses the above class for sending notification.
package org.otp.controllers;
import org.otp.Constants;
import org.otp.services.EmailService;
import org.otp.services.SmsService;
import org.otp.dto.MessageRequest;
import org.otp.dto.MessageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
#Component
public class MessageController {
private static final Logger LOG = LoggerFactory.getLogger(MessageController.class);
#Autowired
SmsService smsService;
public void sendMessageToAlert(#RequestBody MessageRequest messageRequest)
{
String smsStatus = "FAIL";
MessageResponse messageResponse = new MessageResponse();
//1. Nullpointer
smsStatus = smsService.send(messageRequest.getMobileNo(),messageRequest.getMessage());
}
}
Main Class
package org.otp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
#SpringBootApplication
#EnableAsync
public class OtpServiceApplication implements ApplicationRunner
{
public static void main(String[] args) {
SpringApplication.run(OtpServiceApplication.class, args);
}
}
Problem is, I get a nullpointer exception in the (1) stating that my SmsService object is null. And my main class is in package org.otp so the two classes here falls under sub package so no need of component scan.
Therefore I am confused what to do to solve this. I have tried many answers here like adding a #Component annotation and #ComponentScan in main class but nothing works. Could someone please point out my mistake here.
Thanks in advance.
If your #Autowired annotation is not working and throws NPE ,it means that spring fails to create an instance of the component class in the application context . Try to:
Verify that the classes are in class path for scanning and also check to ensure that all auto-wired classes have the annotation #Component to enable them to be picked up during class path scanning.
Check the spring boot start up logs to verify if there are any errors
during bean creation.
Check to ensure all related classes used in the service layer are auto-wired properly and that the injected classes are annotated with #Component .
For further help please share the main application class along with your project structure.
Since you are using springboot , it is preferable to use the sprinboot stereotype annotations instead of the #Component annotation, if you are building a standard springboot web application.
#Service : for the service layer.
#Controller : for the controller layer . Also,DispatcherServlet will look for #RequestMapping on classes which are annotated using #Controller but not with #Component.
In Springboot application's main class add following annotation
#SpringBootApplication
#ComponentScan(
basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
public static void main(String[] args) {
SpringApplication.run(YourSpringMainClass.class, args);
}
}
While using annotations we should configured with #ComponentScan annotation to tell Spring the packages to scan for annotated components. This should be used in mail class(Which class wants to load first) in your case you are working with spring boot so you should use this annotation in Springboot application's main class. Like below
#SpringBootApplication
#ComponentScan(
basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
public static void main(String[] args) {
SpringApplication.run(YourSpringMainClass.class, args);
}
}
I am currently trying out a Spring boot application with Redis.I have a problem related to spring boot concerning redis repositories when I try to execute the program.
When I run the app I get the following error:
2017-09-02 09:21:37.065 INFO 5130 --- [st-startStop-18] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-02 09:21:37.106 WARN 5130 --- [st-startStop-18] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controller': Unsatisfied dependency expressed through method 'setSessionService' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sessionServiceImpl' defined in file [/rezsystem/apache-tomcat-8.0.36/webapps/sessionmanager/WEB-INF/classes/rezg/rezos/sessionmanager/services/SessionServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2017-09-02 09:21:37.118 INFO 5130 --- [st-startStop-18] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-09-02 09:21:37.306 ERROR 5130 --- [st-startStop-18] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
**Description:**
Parameter 0 of constructor in mezg.mezos.sessionmanager.services.SessionServiceImpl required a bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' that could not be found.
**Action:**
Consider defining a bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' in your configuration.
The related source files are listed below
Service Interface
package mezg.mezos.sessionmanager.services;
import java.util.List;
public interface SessionService {
List<String> listAll();
String getById(String Key);
}
Service Implemention
package mezg.mezos.sessionmanager.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import mezg.mezos.sessionmanager.repositories.SessionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
#Service
public class SessionServiceImpl implements SessionService{
private SessionRepository sessionRepository; //error refere to this
#Autowired
public SessionServiceImpl(SessionRepository sessionRepository) {
this.sessionRepository = sessionRepository;
}
#Override
public List<String> listAll() {
List<String> allSessions = new ArrayList<>();
sessionRepository.findAll().forEach(allSessions::add);
return allSessions;
}
#Override
public String getById(String Key) {
return sessionRepository.findOne(Key);
}
}
Repository
package mezg.mezos.sessionmanager.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface SessionRepository extends CrudRepository<String, String> {
}
Controller
package mezg.mezos.sessionmanager.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import mezg.mezos.sessionmanager.services.SessionService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.ui.Model;
#RestController
#RequestMapping(value="/sessionmanager")
public class SessionController {
final static Logger logger = LoggerFactory.getLogger(SessionController.class);
private SessionService sessionService;
#Autowired
public void setSessionService(SessionService sessionService) {
this.sessionService = sessionService;
}
#RequestMapping(value = "/servicecheck", method = RequestMethod.GET)
public String servicecheck() {
return "This is the First Message From Remote session manager service!";
}
#RequestMapping(value ="/all", method = RequestMethod.GET)
public String listAllSessions(Model model){
model.addAttribute("sessions", sessionService.listAll());
return "display all Sessions";
}
#RequestMapping("/session/show/{key}")
public String getProduct(#PathVariable String key, Model model){
model.addAttribute("product", sessionService.getById(key));
return "display selected Sessions";
}
}
Main class
package mezg.mezos.sessionmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan("mezg.mezos.sessionmanager")
public class SessionStoreApplication {
public static void main(String[] args) {
SpringApplication.run(SessionStoreApplication.class, args);
}
Gradle Dependencies
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-redis')
compile('org.springframework.boot:spring-boot-starter-web')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
There were similar scenarios described on this forum and I did try out the suggested solutions but could resolve this issue.Some of these issue are listed below.
Stack overflow Reference
Consider defining a bean of type 'com.ensat.services.ProductService' in your configuration
Consider defining a bean of type 'package' in your configuration [Spring-Boot]
Consider defining a bean of type 'service' in your configuration [Spring boot]
Spring boot CrudRepo Define a bean
Spring boot + redis
Other References
http://www.cnblogs.com/exmyth/p/7119225.html
------------------------UPDATE 1-----------------------
Tried Updating the Main Class with #ComponentScan and #EnableRedisRepositories
package mezg.mezos.sessionmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan({"mezg.mezos.sessionmanager","mezg.mezos.sessionmanager.controller","mezg.mezos.sessionmanager.services","mezg.mezos.sessionmanager.repositories"})
#EnableRedisRepositories("mezg.mezos.sessionmanager.repositories")
public class SessionStoreApplication {
public static void main(String[] args) {
SpringApplication.run(SessionStoreApplication.class, args);
}
}
------------------------UPDATE 2-----------------------
Full Logs
https://gist.github.com/lrrp/3065dff578daa92dacf4bdc78f90c9b5
Any suggestion on how how I can fix this Spring boot error and any best practices to follow in situations such as this?
I read a lot about this kind of problem here, but it seems my code is good but the autowire is not working :
Error creating bean with name 'optionController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private service.InteractionBanque controllers.OptionController.interactionBanque; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [service.InteractionBanque] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Here is the code of my Controller :
package controllers;
package controllers;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import serviceimpl.InteractionBanqueImpl;
#Controller
public class OptionController {
#Autowired
private InteractionBanque interactionBanque;
#RequestMapping(value="/virement",method=RequestMethod.GET)
public String index(Model model, #ModelAttribute Client client) {
model.addAttribute("virement", new Virement());
return "virement";
}
#RequestMapping(value="/virement",method=RequestMethod.POST)
public String index(#ModelAttribute Virement virement, Model model) {
return "options";
}
}
And the Code of my Service :
package serviceimpl;
import java.util.HashMap;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import dao.BanqueDAO;
import daoimpl.BanqueDaoImpl;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import utils.SendRequest;
#Service
public class InteractionBanqueImpl implements InteractionBanque {
public static final int END_ID_BANQUE = 5;
public static final String LOGIN_URL = "/account";
public boolean connecter(Client client) {
some code
}
}
And The code of the interface :
package service;
public interface InteractionBanque {
boolean connecter(Client client);
}
And my Application class define the #SpringBootApplication which should be use to wire everything :
package controllers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
SO I don't get it, for me this should do the work but the autowired is not working.
Help would be appreciated :)
#SpringBootApplication scans only package (recursively) within a class that uses it. InteractionBanqueImpl is in another package.
Create a package 'app' with Application class, and then move to it controllers and and other packages. Should be fine.
As #Mati said, you have a problem with packages.
Create a root package for your application and move everything under it, so you have it something like this:
+ myapp
Application.java
+ controller
+ service
+ serviceimpl
The answers you have about putting your Application class in a parent package of the rest of your code will work, but an alternative, if you don't want to change your package structure, would be to use the #ComponentScan annotation, specifying the packages that contain components you want to autowire, for example:
#ComponentScan(basePackages = {"serviceimpl", ...}