I am new to Spring Boot. I was trying to develop small application in spring boot mvc with neo4j database. Following is my Server
#Configuration
#ComponentScan({ "myproject" })
#EnableAutoConfiguration
#EnableNeo4jRepositories(basePackages = "myproject")
public class Server extends Neo4jConfiguration implements CommandLineRunner
{
public Server()
{
setBasePackage("myproject");
}
#Bean
SpringRestGraphDatabase graphDatabaseService()
{
return new SpringRestGraphDatabase("http://localhost:7474/db/data");
}
#Bean
Mapper mapper()
{
return new DozerBeanMapper();
}
public void run(String... args) throws Exception
{
}
public static void main(String[] args) throws Exception
{
SpringApplication.run(Server.class, args);
}
}
Following is my main class
#Configuration
#ComponentScan({ "myproject.business" })
#EnableNeo4jRepositories(basePackages = "myproject")
public class MainWithStructure extends Neo4jConfiguration implements CommandLineRunner
{
#Autowired
private MyService myService;
public MainWithStructure()
{
setBasePackage("myproject");
}
#Bean
SpringRestGraphDatabase graphDatabaseService()
{
return new SpringRestGraphDatabase("http://localhost:7474/db/data");
}
.......
......
public static void main(String[] args) throws Exception
{
FileUtils.deleteRecursively(new File("accessingdataneo4j.db"));
SpringApplication app = new SpringApplication(MainWithStructure.class);
app.setWebEnvironment(false);
app.run(args);
}
}
Following is my Component class
#Component
public class MyService
{
#Autowired
private Mapper mapper; //Fails to autowire org.dozer.Mapper
.....
}
Following is my Controller class
#RestController
#RequestMapping("/rest")
public class MyController
{
#Autowired
private Mapper mapper; //autowire sucess org.dozer.Mapper
}
I got following Exception when I run main class MainWithStructure
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainWithStructure': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.business.MyService myproject.main.MainWithStructure.MyService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.dozer.Mapper myproject.business.MyService.mapper; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.dozer.Mapper] 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)}
Following is my project structure
demo_project
src/main/java
---myproject.main
------MainWithStructure.java
------Server.java
---myproject.business
------MyService.java
---myproject.rest
------MyController.java
If I autowire org.dozer.Mapper in Controller, it sucessfuly autowired it. BUT if I autowire org.dozer.Mapper in Component class it fails to autowire.
Why it is failing to autowire org.dozer.Mapper only on Component class?
Please make me correct if I wrong. Thank you :)
Your Server is not in one of the packages that you #ComponentScan, so the Mapper is indeed not a bean. Try removing the explicit package from the #ComponentScan (since everything is in a subpackage of the main class that will pick up all the components).
You can add #SpringBootApplication in your main class which has #ComponentScan
which will scan all your sub components in project.
Related
I have a test class in Junit4 that needs to use NutrientListService.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ApplicationContext.class)
public class CalculationTests {
private NutrientListService nutrientService;
#Test
public void someTest()
Result re = Calculator.calculate(response, nutrientService)
}
I was getting a null nutrientService, so I tried to set up an ApplicationContext.
#Configuration
#ComponentScan("myservice")
#ComponentScan("myrepository")
public class ApplicationContext {
#Autowired
NutrientListService nutrientService;
}
However, I get
Error creating bean with name 'nutrientListService': Unsatisfied dependency expressed through field 'nutrientListRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repositories.NutrientListRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
This is the service:
#Service
#Component
public class NutrientListService {
#Autowired
private NutrientListRepository repo;
}
And the repository:
#Repository
public interface NutrientListRepository extends MongoRepository<MyClass, String> {
MyClass findByID(String ID);
}
Any ideas to wire the service properly? I need to pass it for calculation as it is one of the parameters. Do I have to use an application context class or the application-context.xml (which I could not find)? What would be the least obscure way to do this? I thank you.
#Configuration
#ComponentScan("myservice")
#ComponentScan("myrepository")
public class ApplicationContext {
#Bean
NutrientListService nutrientService(){
new NutrientListService()
}
}
And then call the Bean with #Autowired
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ApplicationContext.class)
public class CalculationTests {
#Autowired
NutrientListService nutrientService
#Test
public void someTest()
Result re = Calculator.calculate(response, nutrientService)
}
I'm trying to get the refreshed value of my property apiKey, after modifying it and requesting the /refresh endpoint.
For some reason my bean is unable to get the refreshed value even when annotated with #RefreshScope. I added #RefreshScope on my class as I did for my DatasourceConfig but in this case I'm getting this error :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.application': Initialization of bean failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.application.initTimestamp.transformer.handler': Invocation of init method failed;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'scopedTarget.application': Requested bean is currently in creation: Is there an unresolvable circular reference?
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| scopedTarget.application
└─────┘
Here is my Application.java :
#SpringBootApplication
#EnableConfigServer
#EnableSwagger2
#RefreshScope
public class Application{
#Value("${api.key}")
private String apiKey;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Autowired
private IMonitoringsService monitoringsService;
#Bean
public MessageChannel initTimestampChannel() {
return new DirectChannel();
}
#RefreshScope
#Bean
#InboundChannelAdapter(value = "initTimestampChannel", poller = #Poller(fixedRate = "${start.task.rate}"))
public MessageSource<?> buildRequestMessageSource() {
MethodInvokingMessageSource source = new MethodInvokingMessageSource();
source.setObject(tasksService);
source.setMethodName("requestAllTasks");
System.out.println(apiKey);
return source;
}
}
Yet it's working for my DatasourceConfig :
#RefreshScope
#Configuration
public class DatasourceConfig {
#Value("${spring.datasource.tomcat.max-active}")
private int maxActive;
#RefreshScope
#ConfigurationProperties(prefix = "spring.datasource")
#Bean
public DataSource dataSource() {
DataSource dataSource = DataSourceBuilder.create().build();
org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
ds.setMaxActive(maxActive);
return ds;
}
}
I'm using :
<spring-cloud.version>Edgware.SR2</spring-cloud.version>
<spring-boot-version>1.5.9.RELEASE</spring-boot-version>
As spencergibb suggested, you shouldn't put #SpringBootApplication and #RefreshScope on the same class. Remove #RefreshScope from Application and move the configuration that needs #RefreshScope to a separate class.
#Controller
#EnableAutoConfiguration
public class ControllerShowInfo
{
#RequestMapping("/")
public String rawPage()
{
return "rawPage";
}
#Autowired
stockreviewsRepositoryDao repository;
#RequestMapping("/getBaseInfo")
#ResponseBody
public JSONArray getReviewsInfo()
{
JSONArray jsonArray = new JSONArray();
for (stockreviewsBean reviewBean : repository.findAll())
{
jsonArray.put(reviewBean);
System.out.println(reviewBean.getTitle());
}
return jsonArray;
}
public static void main(String[] args) throws Exception
{
SpringApplication.run(ControllerShowInfo.class, args);
}
}
this is controller layer.
public interface stockreviewsRepositoryDao extends CrudRepository<stockreviewsBean,String>
{
}
this is Dao layer.
when I run ControllerShowInfo.class. There is a problem as follows:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controllerShowInfo': Unsatisfied dependency expressed through field 'repository': No qualifying bean of type [com.yxzh.mapper.stockreviewsRepositoryDao] found for dependency [com.yxzh.mapper.stockreviewsRepositoryDao]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.yxzh.mapper.stockreviewsRepositoryDao] found for dependency [com.yxzh.mapper.stockreviewsRepositoryDao]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
but when I run another .class
#SpringBootApplication
public class Application
{
public static void main(String[] args) throws Exception
{
SpringApplication.run(Application.class, args);
}
}
and implement CommmandLineRunner
#Component
public class DataInitialization implements CommandLineRunner{
#Autowired
stockreviewsRepositoryDao repository;
#Override
public void run(String... args) throws Exception
{
System.out.println("-------------------------------");
int count=0;
for (stockreviewsBean reviewBean : repository.findAll())
{
count++;
System.out.println(reviewBean.getTitle());
}
System.out.println(count);
}
}
It worked well. It really confused me.
Have you tried to annotate
stockreviewsRepositoryDao with #Repository
and
Application with #EnableJpaRepositories(basePackageClasses = {"stockreviewsRepositoryDao.class"})
I have a spring boot spring data application. This was working fine when my repository extended CrudRepository. To get dynamic querying, I extended QueryByExampleExecutor. After extending QueryByExampleExecutor, and run the mvn spring-boot:run, I am getting the below error:
***An exception occured while running. null: InvocationTargetException: Error creating bean with name 'dataSourceInitializerPostProcessor': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.beans.factory.BeanFactory org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.beanFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeProfileRepository': Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)***
Repository Class:
#Transactional
#Repository
public interface EmployeeProfileRepository extends CrudRepository<EmployeeProfile, Long>, QueryByExampleExecutor<EmployeeProfile> {
}
Service Class:
#Service
public class EmployeeProfileService {
#Autowired
private EmployeeProfileRepository empProfileRepository;
public List<EmployeeProfile> searchEmployees(Long id, String firstName, String lastName) {
List<EmployeeProfile> employees = new ArrayList<>();
EmployeeProfile emp = new EmployeeProfile();
emp.setId(id);
emp.setFirstName(firstName);
emp.setLastName(lastName);
Example<EmployeeProfile> example = Example.of(emp);
Iterable<EmployeeProfile> iterable = empProfileRepository.findAll(example);
iterable.forEach(employees::add);
return employees;
}
}
Application class:
#Configuration
#EnableAutoConfiguration
#EnableJpaRepositories("com.employee.dao")
#ComponentScan("com.employee")
#EntityScan("com.employee.dto")
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
I am trying to integrate Spring JPA with MongoDB. My intention is to just retrieve data from mongo DB. I am getting the below error while injecting my repository.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.org.coop.society.data.mongo.repositories.MaterialMasterRepository com.org.coop.security.service.MongoService.materialMasterRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'materialMasterRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
My configuration snippet is given below.
TestMongoDBConfig.java
#Configuration
#EnableMongoRepositories(basePackages = {"com.abc.data.mongo.repositories"})
#ComponentScan(basePackages = "com.abc")
#PropertySource("classpath:applicationTest.properties")
public class TestMongoDBConfig extends AbstractMongoConfiguration {
#Autowired
private Environment env;
#Override
protected String getDatabaseName() {
return "retail";
}
#Override
#Bean
public MongoClient mongo() throws Exception {
MongoClient client = new MongoClient("localhost", 27017);
return client;
}
#Override
protected String getMappingBasePackage() {
return "com.abc.data.mongo.entities";
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), getDatabaseName());
}
}
MaterialMaster.java in com.abc.data.mongo.entities package
#Document(collection = "materialMaster")
public class MaterialMaster {
#Id
private Long materialId;
#Field
private String name;
MaterialMasterRepository.java in com.abc.data.mongo.repositories package
public interface MaterialMasterRepository extends MongoRepository<MaterialMaster, Long> {
}
MongoService.java in com.abc.service package
#Service
public class MongoService {
#Autowired
private MaterialMasterRepository materialMasterRepository;
public void getMaterials() {
List<MaterialMaster> materials = materialMasterRepository.findAll();
System.out.println(materials);
}
}
Junit class looks like below
#RunWith(SpringJUnit4ClassRunner.class)
#ComponentScan(basePackages = "com.abc")
#ContextHierarchy({
#ContextConfiguration(classes={TestMongoDBConfig.class})
})
public class ModuleWSTest {
#Autowired
private MongoService mongoService;
#Test
public void testModule() {
mongoService.getMaterials();
}
}
I have tried all possible changes (as per my knowledge) but no luck. Any help is really appreciated.
The error message is little confusing. I was using latest spring-data-mongodb (1.8.4.RELEASE). Once I downgraded the dependency to 1.6.0.RELEASE then the above configuration started working.