Spring can't find repository bean - spring-boot

I'm using spring boot with spring data jdbc and I got trouble with run my app
I have StudentService class:
package ru.turnip.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import ru.turnip.model.Student;
import ru.turnip.repository.StudentRepository;
import ru.turnip.utils.student.BusyStudents;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
#Service
public class StudentService {
private final BusyStudents busyStudents;
private final StudentRepository studentRepository;
public StudentService(BusyStudents busyStudents, StudentRepository studentRepository) {
this.busyStudents = busyStudents;
this.studentRepository = studentRepository;
}
...
}
And StudentRepository interface:
package ru.turnip.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import ru.turnip.model.Student;
import java.util.UUID;
#Repository
public interface StudentRepository extends CrudRepository<Student, UUID> { }
So, when I try to run app, I get an eror, and I can't figure out where the problem is.
That my config class:
package ru.turnip;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent;
import org.springframework.scheduling.annotation.EnableScheduling;
import ru.turnip.model.Student;
import java.time.Clock;
import java.util.UUID;
#ComponentScan
#Configuration
#EnableScheduling
public class ApplicationConfig {
#Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
#Bean
public ApplicationListener<BeforeSaveEvent> idGenerator() {
return event -> {
var entity = event.getEntity();
if (entity instanceof Student) {
((Student) entity).setId(UUID.randomUUID());
}
};
}
}
And project structure:
I tried to explicitly set package to be scanned, and also moved the repository to the package with the config. Also I tried to annotate with #Autowired field and constructor in StudentService

Related

Missing bean in controller even after adding ComponentScan annotation

I am trying to run a spring boot application which gets a list of names of people from the database. I am getting the below error :
Description:
Field peopleserviceinterface in com.sample.lombpackdemo.controller.FriendController required a bean of type 'com.sample.lombpackdemo.service.FriendsServiceInterface' 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.sample.lombpackdemo.service.FriendsServiceInterface' in your configuration.
package com.sample.lombpackdemo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sample.lombpackdemo.entity.Friends;
import com.sample.lombpackdemo.rowmapper.FriendsRowMapper;
import com.sample.lombpackdemo.service.FriendsServiceInterface;
#CrossOrigin(origins = { "http://localhost:3000"})//to allow access from other servers
#RestController
#RequestMapping("/code")
#ComponentScan(basePackages="com.sample.lombpackdemo.service")
public class FriendController {
#Autowired
private FriendsServiceInterface peopleserviceinterface;//autowire the service
#GetMapping("/all")
public ResponseEntity<List<Friends>> getAllPeople(){
List <Friends> listOfAllPpl = peopleserviceinterface.getAllFriends();
System.out.println("Getting all friends"+listOfAllPpl.toString());
return new ResponseEntity<List<Friends>>(listOfAllPpl,HttpStatus.OK);
}
}
The FriendServiceInterface class is as below:
package com.sample.lombpackdemo.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.sample.lombpackdemo.entity.Friends;
#Component
public interface FriendsServiceInterface {
public List<Friends> getAllFriends();
}
The FriendService class:
package com.sample.lombpackdemo.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.sample.lombpackdemo.entity.Friends;
import com.sample.lombpackdemo.repos.FriendsRepo;
import com.sample.lombpackdemo.rowmapper.FriendsRowMapper;
#Service
#Profile("devel")//added to disable CORS only on development time
#Configuration
#Component
public class FriendService implements FriendsServiceInterface {
#Autowired
private FriendsServiceInterface peopleserviceinterface;
#Autowired
private FriendsRepo pplRepo;//should always autowire repository
#Autowired
private JdbcTemplate jdbc;
private static long idCounter = 0;
//FriendsRowMapper fRowMap=new FriendsRowMapper();
#Override
public List<Friends> getAllFriends() {
String sql="select f_name from list_friends";
return jdbc.query(sql, new FriendsRowMapper() );
/*
List<Friends> ppList= (List<Friends>) fRowMap.findAll();
try {
System.out.println("Repository value"+pplRepo.findAll());
System.out.println("Inside findAll of service class" +ppList.toString() );
}
catch(Exception e)
{
}
return ppList;
//
*/}
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
//registry.addMapping("/save-javaconfig").allowedOrigins("http://localhost:3000");
}
};
}
Please let me know what else needs to be changed. I have tried adding Component annotation to FriendService class and ComponentScan annotation to the controller class.
Edited to add JdbcConfig class
package com.sample.lombpackdemo.repos;
//import java.util.logging.Logger;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
#Configuration
#ComponentScan(basePackages = "com.sample.lombpackdemo")
public class SpringJdbcConfig {
protected final Logger log = LoggerFactory.getLogger(getClass());
#Bean
public DataSource mysqlDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/person_example");
dataSource.setUsername("root");
dataSource.setPassword("subfio");
return dataSource;
}
#Bean(name = "dbProductService")
#ConfigurationProperties (prefix = "spring.datasource")
#Primary public DataSource createProductServiceDataSource()
{ System.out.println("Inside db cofig ");
return DataSourceBuilder.create().build(); }
}
}

What does 'Propagation.NEVER Executes non-transactionally' mean in Spring?

In the code below, the save operation in createDevice method inside DeviceService class will not be executed inside a transaction, what does it mean that this operation is not executed inside a transaction?
Is it possible to execute an operation on the database without a transaction?
package controller;
import model.Device;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import service.DeviceService;
#RestController
public class DeviceController {
#Autowired
private DeviceService deviceService;
#PostMapping("/devices")
#ResponseStatus(HttpStatus.CREATED)
public void createDevice(#RequestBody Device device) {
deviceService.createDevice(device);
}
}
--
package service;
import model.Device;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import repository.DeviceRepository;
#Service
public class DeviceService {
#Autowired
private DeviceRepository deviceRepository;
#Transactional(propagation = Propagation.NEVER)
public void createDevice(Device device) {
deviceRepository.save(device);
}
}
--
package repository;
import model.Device;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DeviceRepository extends JpaRepository<Device, Integer> {
}
--
package model;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Device {
#Id
private Integer id;
private String name;
}
Edit
I'm using MySQL database.
The Operation gets executed successfully.
Any details on how this gets executed without a transaction? What is being done behinde the scene?
What is the difference between executing an operation inside a transaction and without a transaction?

Spring Boot #ComponentScan finds candidate component class but does not inject #Configuration beans

I have #SpringBootApplication with #ComponentScan({"myPackage"}) and in myPackage I have a class annotated with #Configuration or #Component. When I start the spring boot app the logs show:
DEBUG [main] org.sprin.conte.annot.ClassPathScanningCandidateComponentProvider 437 scanCandidateComponents: Identified candidate component class: file [C:\Web\project\bin\main\myPackage\Config.class]
but then nothing injects the class or its beans into the app...
It looks related to this
CODE
package app;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.gemfire.config.annotation.EnableLogging;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
#SpringBootApplication
#ComponentScan({"myPackage"})
#EntityScan({"myPackage"})
#EnableGemfireRepositories("region")
#EnableLogging(logLevel="info", logFile="geodeApi.log")
public class Web {
private static final Logger log = LogManager.getLogger(Web.class);
public static void main(String[] args) {
log.info("In Main");
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Web.class, args);
log.info("Out Main");
}
}
In myPackage.Client
package myPackage;
import java.util.UUID;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.logging.log4j.LogManager;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.cache.config.EnableGemfireCaching;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableClusterDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnablePdx;
import org.springframework.data.gemfire.config.annotation.EnablePool;
import org.springframework.data.gemfire.config.annotation.EnablePool.Locator;
import org.springframework.data.gemfire.config.annotation.EnableStatistics;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
#ClientCacheApplication(name = "Web", logLevel = "debug")
#EnablePool(name = "webPool", subscriptionEnabled = true)
#EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.CACHING_PROXY)
#EnablePdx
#EnableStatistics
#EnableGemFireHttpSession(poolName = "webPool")
#EnableGemfireCaching
// #EnableWebFlux
public class Client {
private static final Logger log = LogManager.getLogger(Client.class);
#Resource
private Region<String, String> myAdmin;
#PreDestroy
public void onDestroy() throws Exception {
log.info("onDestroy");
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
myAdmin.put(guid, "Web Shutdown");
log.traceExit();
}
#Bean
ApplicationRunner StartedUp(){
log.traceEntry("StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
myAdmin.put(guid, "Web Started");
log.traceExit();
};
}
// Required to resolve property placeholders in Spring #Value annotations.
#Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
log.traceEntry("propertyPlaceholderConfigurer");
return new PropertySourcesPlaceholderConfigurer();
}
}
In myPackage.Config
package myPackage;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
#Configuration
public class Config {
private static final Logger log = LogManager.getLogger(Config.class);
#Bean("myRegion")
public Region<String, Object> myRegion(GemFireCache cache) {
log.traceEntry();
Region<String, Object> r = cache.getRegion("myRegion");
r.setUserAttribute(ClientRegionShortcut.CACHING_PROXY);
return r;
}
}
In Config class while defining the bean you are using Region<String, Object> as return type. Where as in the your Client class you define Region<String, String>. Here it is clearly a type mismatch and hence bean will not load.

Field required a bean of type that could not be found.'

The structure has no problem. The spring-boot can scan UserMapper but can't scan UserService. I tried to give my UserService #Mapper component, then it could be scanned. But I don't know how to use other methods to let it be scanned. I tried #Service but it doesn't work.
package com.mywebprojet.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MywebprojectApplication {
public static void main(String[] args) {
SpringApplication.run(MywebprojectApplication.class, args);
}
}
package com.mywebprojet.springboot.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.mywebprojet.springboot.entity.User;
import com.mywebprojet.springboot.mapper.UserMapper;
import com.mywebprojet.springboot.service.UserService;
#RestController
#RequestMapping(value = "user")
public class UserController {
#Autowired
private UserMapper userMapper;
#Autowired
private UserService userService;
}
package com.mywebprojet.springboot.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.mywebprojet.springboot.entity.User;
#Service
public interface UserService{
void insert(User user);
}
You should write a UserService Implementation and have it annotated with #Service, not the interface. For example:
#Service
public class UserServiceImpl implements UserService {
#Override
public void insert(User user) {
// Implementation
}
}

Field ** in com.** required a bean of type 'com.**' that could not be found

I'm following this tutorial and I'm having some trouble starting my application.
When I run mvn spring-boot:run in the backend folder I get the following error:
Field movieRepository in com.movieseat.services.impl.MovieServiceImpl required a bean of type 'com.movieseat.repositories.MovieRepository' that could not be found.
MovieServiceIml.java
package com.movieseat.services.impl;
// Java imports
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
// Spring imports
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
// Project imports
import com.movieseat.models.Movie;
import com.movieseat.services.MovieService;
import com.movieseat.repositories.MovieRepository;
#Service
public class MovieServiceImpl implements MovieService {
#Autowired private MovieRepository movieRepository;
#Override public List<Movie> getAllmovies() {
List<Movie> movies = new ArrayList<Movie>();
Iterator<Movie> iterator = movieRepository.findAll().iterator();
while (iterator.hasNext()) {
movies.add(iterator.next());
}
return movies;
}
}
MovieRepository.java
package com.movieseat.repositories;
// Java imports
import java.io.Serializable;
// Spring imports
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
// Project imports
import com.movieseat.models.Movie;
#Repository
public interface MovieRepository extends CrudRepository<Movie, Serializable> {}
The following structure is used:
com
movieseat
Application.java
controllers
MovieController.java
models
MovieModel.java
repositories
MovieRepository.java
services
impl
MovieServiceImpl.java
MovieService.java
And this is my Application.java:
package com.movieseat;
// Spring importss
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan({"com.movieseat.*"})
#EnableJpaRepositories("com.movieseat.repositories.*")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My thought is that using #EnableJpaRepositories("com.movieseat.repositories.*") would make all repositories accessible. But I'm doing something wrong.
Try it without * (wildcard),
#EnableJpaRepositories("com.movieseat.repositories")
Make sure you have the #Entity annotation on your Movie.

Resources