I starting in Spring MVC with the Book Spring in Action, I'm making the exercise of the chapter 5, with the Spitter application but I got the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'spittleController' defined in file [C:\xampp\htdocs.metadata.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\spitter\WEB-INF\classes\com\spitter\web\SpittleController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.spitter.data.SpittleRepository]: : No qualifying bean of type [com.spitter.data.SpittleRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.spitter.data.SpittleRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
I got the project here in github: https://github.com/kevingcfcb88/spitter.git
I already do my research but nothing seems to work.
I'm using STS and Maven, this is the structure of the app:
Here is my pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.spitter.config</groupId>
<artifactId>spitter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spitter</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework.version>4.1.5.RELEASE</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>spitter</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<finalName>spitter</finalName>
</build>
And my config files:
SpittrWebAppInitializer.java
package com.spitter.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
WebConfig.java
package com.spitter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.spitter.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
RootConfig.java
package com.spitter.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages = { "com.spitter.data" }, excludeFilters = {#Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {
}
As #mh-dev explained, you need an implementation of SpittleRepository. Try adding this class and see if your code can run:
public class SpittleRepositoryImpl implements SpittleRepository {
List <Spittle> findSpittles(long max, int count) {
System.out.println("I need a real implementation! "
+ "I received max as " + max + " and count as " + count + ".");
}
}
I would suggest re-reading the relevant sections of the book to make sure you didn't miss anything.
You just need to add a repository implementation of SpittleRepository with #Repository in the header, because even though you have added implementation classes, spring IOC is unaware of actual dependency and the example in the book should have worked if you had put all the java files in the same package hierarchy with repository implementation.
#Repository
public class SpittleRepositoryDAO implements SpittleRepository {
public SpittleRepositoryDAO() {
}
#Override
public List<Spittle> findSpittles(long max, int count) {
List<Spittle> spittles = new ArrayList<Spittle>();
for (int i = 0; i < count; i++) {
spittles.add(new Spittle("Spittle " + i, new Date()));
}
return spittles;
}
}
I know this code. It used to give me serious headache 2 years ago.
The eror is in the code OR the book itslef.
Go to the publishers site and download the updated sourcecode. here
or
https://www.manning.com/books/spring-in-action-fourth-edition
Here is the implementation of the repository:
package com.spitter.web;
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 com.spitter.data.SpittleRepository;
#Controller
#RequestMapping("/spittles")
public class SpittleController {
private SpittleRepository spittleRepository;
#Autowired
public SpittleController(SpittleRepository spittleRepository) {
this.spittleRepository = spittleRepository;
}
#RequestMapping(method = RequestMethod.GET)
public String spittles(Model model) {
model.addAttribute("spittleList", spittleRepository.findSpittles(Long.MAX_VALUE, 20));
return "spittles";
}
}
yep, the problem is that you need an implementation of SpittleRepository. Cause you can't have an interface as bean, you know. The scan component need at least one implementation of it and with the annotation #Component. That's it ;)
Related
Ive been trying to follow a few basic examples to create a rest api to connect to a local mysql server
However I keep running to this error
Consider defining a bean of type 'org.example.database.MessagesRepository' in your configuration.
Here is my current project layout
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>messagesApi</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Main.java
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
#EnableAsync
#SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
MessagesApi
package org.example.api;
import org.example.models.Messages;
import org.example.database.MessagesRepository;
import org.example.models.MessagesRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#Controller
#RequestMapping("/chats")
public class MessagesApi {
#Autowired
MessagesRepository messagesRepository;
#GetMapping("id")
public ResponseEntity<Messages> getAllChatsById(#RequestBody MessagesRequest messageRequest) {
return new ResponseEntity<>(messagesRepository.findByTextId(messageRequest.getTextId()), HttpStatus.OK);
}
#GetMapping("username")
public ResponseEntity< List<Messages>> getAllChatsByUserName(#RequestBody MessagesRequest messageRequest) {
return new ResponseEntity<>(messagesRepository.findByUserName(messageRequest.getUserName()), HttpStatus.OK);
}
#PostMapping
public ResponseEntity<Long> postMessage(#RequestBody Messages message ){
//make Id
Long id = 1234L;
message.setTextId(id);
messagesRepository.save(message);
return new ResponseEntity<>(id, HttpStatus.CREATED);
}
}
MessagesRespository
package org.example.database;
import org.example.models.Messages;
import org.springframework.data.repository.JpaRepository;
import java.util.List;
public interface MessagesRepository extends JpaRepository<Messages, Long> {
List<Messages> findByUserName(String userName);
Messages findByTextId(Long textId);
}
applications.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=passWord
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Ive tried adding
#EnableJpaRepositories
But kept getting
``Consider defining a bean named 'entityManagerFactory' in your configuration.
When removing
exclude={DataSourceAutoConfiguration.class}
I would get
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
I am not sure where to move forward from here
public interface MessagesRepository extends JpaRepository<Messages, Long> {
rather should be
#Repository
public interface MessagesRepository extends JpaRepository<Messages, Long> {
to make below code work
#Autowired
MessagesRepository messagesRepository;
also exclude from main class
exclude={DataSourceAutoConfiguration.class}
Sometimes spring is not able to scan your entity classes or your configuration classes so use this it will work fine
#SpringBootApplication
#ComponentScan({"org.example"})
#EntityScan("org.example")
#EnableJpaRepositories("org.example")
public class WebServiceApplication extends SpringBootServletInitializer {
}
I started with a simple project using spring jpa and a simple maven class just to test this basic behavior. Everything worked fine. My next step was to divide this single project into two projects in order to have a persistence project responsible for data access and another one to be enriched with business logic. This is where everything breaks. The proof that this is related to java modules is that If I delete module-info.java on both projects everything works fine.
If I simply run the application I get
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/instrument/IllegalClassFormatException
at spring.data.jpa#2.7.3/org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension.getConfigurationInspectionClassLoader(JpaRepositoryConfigExtension.java:239)
at spring.data.commons#2.7.3/org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport.getRepositoryConfigurations(RepositoryConfigurationExtensionSupport.java:97)
at spring.data.commons#2.7.3/org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:159)
at spring.data.commons#2.7.3/org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:106)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:396)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:395)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:157)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343)
at spring.context#5.3.23/org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
at spring.context#5.3.23/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
at spring.context#5.3.23/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
at spring.context#5.3.23/org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
at spring.context#5.3.23/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
at spring.context#5.3.23/org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93)
at test/org.test.Main.main(Main.java:15)
Caused by: java.lang.ClassNotFoundException: java.lang.instrument.IllegalClassFormatException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 17 more
If I debug it, it starts complaining about missing classes (Derby, hibernate, etc).
All this leads me to believe that the problem is on java module declaration, but I don't know how can I solve this..
This is my file structure:
- test
-- src.main.java
--- org.test
---- Config.java
---- Main.java
--- module-info.java
--- src.main.resources
---- org/test/application.properties
-- pom.xml
- test-persistence
-- src.main.java
--- org.test.persistence
---- CustomRepository.java
---- CustomRepositoryImpl.java
---- Entity.java
---- MyRepository.java
---- PersistenceConfiguration.java
--- module-info.java
-- pom.xml
And here are the files:
test pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.version>5.3.23</spring.version>
<spring-data.version>2.7.3</spring-data.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>test-persistence</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
</dependencies>
</project>
test module-info:
module test {
requires testPersistence;
requires spring.context;
requires spring.beans;
requires spring.core;
requires spring.instrument;
opens org.test;
}
Config.java:
package org.test;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.test.persistence.PersistenceConfiguration;
#Configuration
#ComponentScan(basePackages = "org.test")
#Import(PersistenceConfiguration.class)
public class Config {
}
Main.java
package org.test;
import java.util.List;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.test.persistence.Entity;
import org.test.persistence.MyRepository;
public class Main {
public static void main(String[] args) {
System.out.println("Running java " + Runtime.version().feature());
AnnotationConfigApplicationContext appCtx = new AnnotationConfigApplicationContext(Config.class);
MyRepository repo = appCtx.getBean(MyRepository.class);
List<Entity> result = repo.findOrderedByLastUsedLimitedTo(2);
}
}
application.properties:
spring.jpa.generate-ddl=true
spring.jpa.defer-datasource-initialization=true
spring.jpa.database-platform=org.hibernate.dialect.DerbyDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverClassName=org.apache.derby.iapi.jdbc.AutoloadedDriver
spring.datasource.url=jdbc:derby:eTimer;create=true
test-persistence pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test-persistence</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.version>5.3.23</spring.version>
<spring-data.version>2.7.3</spring-data.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
test-persistence module-info.java:
module testPersistence {
requires java.persistence;
requires java.sql;
requires spring.data.commons;
requires spring.data.jpa;
requires spring.orm;
requires spring.jdbc;
requires spring.tx;
requires spring.context;
opens org.test.persistence;
exports org.test.persistence to test;
}
CustomRepository.java:
package org.test.persistence;
import java.util.List;
import org.springframework.stereotype.Repository;
#Repository
public interface CustomRepository {
List<Entity> findOrderedByDescriptionLimitedTo(int maxItems);
}
CustomRepositoryImpl.java:
package org.test.persistence;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class CustomRepositoryImpl implements CustomRepository {
#PersistenceContext
private EntityManager entityManager;
#Override
public List<Entity> findOrderedByDescriptionLimitedTo(int limit) {
return entityManager.createQuery("SELECT p FROM Entity p ORDER BY p.description", Entity.class)
.setMaxResults(limit).getResultList();
}
}
Entity.java:
package org.test.persistence;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#javax.persistence.Entity
#Table(name = "Entity")
public class Entity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String description;
public Entity() {
super();
}
public Entity(Long id, String description) {
super();
this.id = id;
this.description = description;
}
}
MyRepository.java:
package org.test.persistence;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface MyRepository extends JpaRepository<Entity, Long>, CustomRepository {
Entity save(Entity task);
}
PersistenceConfiguration.java:
package org.test.persistence;
import java.io.File;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
#Configuration
#EnableJpaRepositories("org.test.persistence")
#PropertySource("org/test/application.properties")
public class PersistenceConfiguration {
private static final String DRIVER_CLASS_NAME = "org.apache.derby.iapi.jdbc.AutoloadedDriver";
private static final String DATA_SOURCE_DRIVER_URL = "jdbc:derby:test;create=true";
private static final String DATA_SOURCE_USER = null;
private static final String DATA_SOURCE_PASSWORD = null;
#Bean("entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
System.setProperty("derby.system.home", System.getProperty("user.home") + File.separatorChar + "test");
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setPackagesToScan("org.test");
entityManagerFactoryBean.setPersistenceUnitName("system");
entityManagerFactoryBean.setDataSource(systemDataSource());
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.DERBY);
adapter.setShowSql(true);
adapter.setGenerateDdl(true);
entityManagerFactoryBean.setJpaVendorAdapter(adapter);
return entityManagerFactoryBean;
}
#Bean
DataSource systemDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DRIVER_CLASS_NAME);
dataSource.setUrl(DATA_SOURCE_DRIVER_URL);
dataSource.setUsername(DATA_SOURCE_USER);
dataSource.setPassword(DATA_SOURCE_PASSWORD);
return dataSource;
}
#Bean(name="transactionManager")
public PlatformTransactionManager systemTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory((entityManagerFactory().getObject()));
return transactionManager;
}
}
help please?
I'm coding microservices app based on Spring Cloud. I launched Eureka Server and now i'm coding a car-service. It worked when I didn't have any Autowiring in project. After adding Repository, Service and changing Controller the car-service doesn't launch.
When I added #SpringBootApplication("com.carrental.carservice.repository") application started but Rest API doesn't work and return 404. I tried with #Qualifier and naming Repository but still doesn't work.
There is an error when starting:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.carrental.carservice.service.impl.CarTypeServiceImpl required a bean of type 'com.carrental.carservice.repository.CarTypeRepository' that could not be found.
Action:
Consider defining a bean of type 'com.carrental.carservice.repository.CarTypeRepository' in your configuration.
And there is a WARN in logs:
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.carrental.carservice.repository.CarTypeRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
pom.xml of car service
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>carrental</artifactId>
<groupId>com.carrental</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>car-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.9.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
</dependencies>
</project>
starting application file
package com.carrental.carservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#EnableEurekaClient
//#ComponentScan("com.carrental.carservice.repository")
public class CarServiceApp {
public static void main(String[] args) {
SpringApplication.run(CarServiceApp.class, args);
}
}
controller
package com.carrental.carservice.controller;
import com.carrental.carservice.dto.CarTypeDto;
import com.carrental.carservice.model.entity.CarType;
import com.carrental.carservice.service.CarTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RestController
#RequestMapping("/car")
public class CarTypeController {
private final CarTypeService carTypeService;
#Autowired
public CarTypeController(CarTypeService carTypeService){
this.carTypeService = carTypeService;
}
#PostMapping("/cartype/add")
public ResponseEntity<CarTypeDto> addCarType(#Valid #RequestBody CarTypeDto dto){
CarType entity = Mapper.mapToCarTypeEntity(dto);
this.carTypeService.add(entity);
return new ResponseEntity<CarTypeDto>(Mapper.mapToCarTypeDto(entity), HttpStatus.CREATED);
}
#GetMapping
public String get(){
return "jajo";
}
}
service
package com.carrental.carservice.service.impl;
import com.carrental.carservice.model.entity.CarType;
import com.carrental.carservice.repository.CarTypeRepository;
import com.carrental.carservice.service.CarTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class CarTypeServiceImpl implements CarTypeService {
private final CarTypeRepository carTypeRepository;
#Autowired
public CarTypeServiceImpl(CarTypeRepository carTypeRepository){
this.carTypeRepository = carTypeRepository;
}
#Override
public void add(CarType carType) {
if(this.carTypeRepository.existsByName(carType.getName()))
return;
this.carTypeRepository.save(carType);
}
#Override
public List<CarType> getAll() {
return this.carTypeRepository.findAll();
}
#Override
public void update(CarType carType) {
if(this.carTypeRepository.existsById(carType.getId()))
this.carTypeRepository.save(carType);
}
#Override
public void delete(CarType carType) {
this.carTypeRepository.delete(carType);
}
}
repository
package com.carrental.carservice.repository;
import com.carrental.carservice.model.entity.CarType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CarTypeRepository extends JpaRepository<CarType, Long> {
boolean existsByName(String name);
CarType getByName(String name);
boolean existsById(Long id);
}
I tried a lot of stuff and still doesn't work. Can you help, please?
i think you need to use feignClient to avoid this exception.i had similar issue and added
#EnableFeignClients to my ApplicationClass and its dependency to your pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId
</dependency>
I have an error that I can't track down. I'm new so sorry if I missed this in the searches, but I tried several things and no luck.
UserApi.java:
package com.jsp.jsp;
import com.jsp.models.User;
import com.jsp.services.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
class UserApi {
private final UserService userService;
public UserApi(UserService userService) {
this.userService = userService;
}
#RequestMapping(value="/api/user", method=RequestMethod.POST)
public User createUser(
#RequestParam(value="name", required=true) String name,
#RequestParam(value="email", required=true) String email,
#RequestParam(value="password", required=true) String password,
#RequestParam(value="confirm", required=true) String confirm)
{
User u = this.userService.createUser(new User(name, email, password));
return u;
}
}
UserRepository.java:
package com.jsp.repositories;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import com.jsp.models.User;
import org.springframework.data.repository.CrudRepository;
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByEmail(String email);
Optional<User> findById(Long id);
List<User> findAll();
}
Server.java
package com.jsp.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication(scanBasePackages={"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#RestController
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
UserService.java
package com.jsp.services;
import java.util.List;
import com.jsp.models.User;
import com.jsp.repositories.UserRepository;
import org.springframework.stereotype.Service;
#Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> allUsers() {
return this.userRepository.findAll();
}
public User createUser(User u) {
return this.userRepository.save(u);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.jsp</groupId>
<artifactId>jsp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
So in short, when I run the above project in VSCode, it errors out with the following:
2019-02-23 19:07:52.744 WARN 25412 --- [ restartedMain]
ConfigServletWebServerApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userService' defined in file
[C:\Users\Alex\Documents\dojo\javatown\everything\target\classes\com\jsp\services\UserService.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.jsp.repositories.UserRepository'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
My understanding is that the repository I made should be automatically turned into a bean and then wire itself up to the service I made. However, that seems to be not happening. My example videos are using MySQL -- will that make a difference? Am I using the right driver for Postgres 11? I'm super lost.
Some remarks and suggestions:
1.add autowired annotation on your constructor, it is clearer what you need spring to do.
#Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
2. I don't understand #RestController annotation on your main class.
#SpringBootApplication(scanBasePackages {"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#RestController --> THIS CAN BE REMOVED
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
3.You should add #EnableJpaRepositories("com.jsp.repositories") on your spring boot application => it will scan the repositories in that package.
#SpringBootApplication(scanBasePackages {"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#EnableJpaRepositories("com.jsp.repositories")
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
I was trying out a sample springboot project. But in the half way i got stuck up with this problem.
My Controller.java
package org.springbootdemo5.springbootdemo5.controler;
import org.springboot5.springbootdemo5.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class SampleRestController {
#Autowired
private TaskService taskService;
#GetMapping("/hello")
public String hello(){
return "Hello World!!!";
}}
My Task Service
package org.springboot5.springbootdemo5.service;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import org.springboot5.springbootdemo5.dao.TaskRepository;
import org.springboot5.springbootdemo5.model.Task;
import org.springframework.stereotype.Service;
#Service
#Transactional
public class TaskService {
private final TaskRepository taskRepository;
public TaskService(TaskRepository taskRepository) {
this.taskRepository = taskRepository;
}
public List<Task> findAll(){
List<Task> tasks = new ArrayList<>();
for(Task task : taskRepository.findAll()){
tasks.add(task);
}
return tasks;
}
public Task findTask(int id){
return taskRepository.findOne(id);
}
public void save(Task task){
taskRepository.save(task);
}
public void delete(int id){
taskRepository.delete(id);
}}
My Task Repository
package org.springboot5.springbootdemo5.dao;
import org.springboot5.springbootdemo5.model.Task;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
public abstract class TaskRepository implements CrudRepository<Task, Integer>
{
}
And this my Initializer
package org.springbootdemo5.springbootdemo5;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan("org.springboot5.springbootdemo5")
public class Springbootdemo5Application {
public static void main(String[] args) {
SpringApplication.run(Springbootdemo5Application.class, args);
}}
All the annotations are provided properly and pom.xml is also correct but still i am getting exception like
Exception
encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error
creating bean with name 'taskService' defined in file
Unsatisfied dependency
expressed through constructor parameter 0; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'org.springboot5.springbootdemo5.dao.TaskRepository'
available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {}
Description:
Parameter 0 of constructor in
org.springboot5.springbootdemo5.service.TaskService required a bean of type
'org.springboot5.springbootdemo5.dao.TaskRepository' that could not be
found.
Action:
Consider defining a bean of type
'org.springboot5.springbootdemo5.dao.TaskRepository' in your configuration.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springbootdemo5</groupId>
<artifactId>springbootdemo5</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springbootdemo5</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>9.0.0.M26</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Anybody can solve this ?
Any help is always welcome.
Thank you.
Try changing your TaskRepository
to
public interface TaskRepository extends CrudRepository<Task, Integer>
Check the bean ID mentioned in the xml and the member in the Java file should be same , which is case sensitive.
config.xml
<bean id="reportServicePdf" class="my.local.spring.sprintlex.ReportService">
<constructor-arg name="numberOfPage" value="11" /> //<====Here
</bean>
ReportService.java:
public class ReportService {
#Value("100")
private int numberOfPage;//<====Here
::
::
}