I'm trying to learn spring using some internet courses. I have problem with #Autowired and I'm still getting Error: org.springframework.beans.factory.UnsatisfiedDependencyException
I have found many similar problems, but no one suits mine.
My Product class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table
public class Product {
#Id
private int id;
private String name;
#Column(name = "description")
private String desc;
private double price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Interface ProductRepository:
import HIB_UD_01.product.entities.Product;
import org.springframework.data.repository.CrudRepository;
public interface ProductRepository extends CrudRepository<Product, Integer> {
}
ProductdataApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ProductdataApplication {
public static void main(String[] args) {
SpringApplication.run(ProductdataApplication.class, args);
}
}
And my Test class:
import HIB_UD_01.product.entities.Product;
import HIB_UD_01.product.repos.ProductRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ProductdataApplicationTests {
#Autowired
ProductRepository repository;
#Test
public void contextLoads() {
}
#Test
public void testCreate() {
Product product = new Product();
product.setId(1);
product.setName("Iphone");
product.setDesc("Awesome");
product.setPrice(1000d);
repository.save(product);
}
}
And last,my properites file:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
I should put data about product into db, but I get an error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'HIB_UD_01.product.ProductdataApplicationTests': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'HIB_UD_01.product.repos.ProductRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
You probably have to enable repositories on your SpringBootApplication class (or in a separate configuration class):
https://www.concretepage.com/spring-boot/spring-boot-crudrepository-example
If that doesn't work, make sure your SpringBootApplication class is a package higher then the rest of your classes, so SpringBoot can autodetect your beans. (And you can try to annotate your repository with #Repository then, to make sure SpringBoot autodetects your repository.)
Also see:
https://dzone.com/articles/the-springbootapplication-annotation-example-in-ja
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.html
OK, problem fixed. I added #Repository to ProductRepository. I cleared repository folder and download new fresh repositories.
Then I have error with time zone in connection to MySQL. So I edit my properities file:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Thank you for your help!
Related
Hello there I am new to spring boot, i am getting this error since a while, unfortunately can't fix it. I am googling since then but still not find what i did wrong. I believe the error exists in the Service Class. I tried to remove the field injection ( #Autowired) and implemented as a constructor injection but that did not work as well Find below my code:
Entity:
package com.devops.maven.cars_api_maven.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#Entity
#Table(name = "CARS")
#SequenceGenerator(name="seq", initialValue=4, allocationSize=100)
public class Car {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
private Long id;
String manufacturer;
String model;
int build;
public Car() {
}
public Car(Long id, String manufacturer, String model, int build) {
this.id = id;
this.manufacturer = manufacturer;
this.model = model;
this.build = build;
}
public Long getId() {
return id;
}
public String getManufacturer() {
return manufacturer;
}
public String getModel() {
return model;
}
public int getBuild() {
return build;
}
public void setId(Long id) {
this.id = id;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public void setModel(String model) {
this.model = model;
}
public void setBuild(int build) {
this.build = build;
}
}
DAO
package com.devops.maven.cars_api_maven.repositories;
import com.devops.maven.cars_api_maven.model.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CarsRepository extends JpaRepository<Car, Long> {
}
Main
package com.devops.maven.cars_api_maven;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication (
exclude = {DataSourceAutoConfiguration.class },
scanBasePackages={
"com.devops.maven", "com.devop.application"}
)
public class CarsApplication {
public static void main(String[] args) {
SpringApplication.run(CarsApplication.class, args);
}
}
Service Class
package com.devops.maven.cars_api_maven;
import com.devops.maven.cars_api_maven.model.Car;
import com.devops.maven.cars_api_maven.repositories.CarsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping("cars")
#Service
public class CarsController {
#Autowired
private CarsRepository repository;
#GetMapping
public List<Car> getCars() {
return repository.findAll();
}
#PostMapping
public Car addCar(#RequestBody Car car) {
return repository.save(car);
}
#SuppressWarnings("deprecation")
#GetMapping(value = "/{id}")
public Car getCarById(#PathVariable("id") long id) {
return repository.getOne(id);
}
#DeleteMapping(value = "/{id}")
public void removeCarById(#PathVariable("id") long id) {
repository.deleteById(id);
}
}
Error output:
*************************** APPLICATION FAILED TO START
Description:
Field repository in com.devops.maven.cars_api_maven.CarsController
required a bean of type
'com.devops.maven.cars_api_maven.repositories.CarsRepository' 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.devops.maven.cars_api_maven.repositories.CarsRepository' in your
configuration.
Please remove exclude = {DataSourceAutoConfiguration.class } from below class and run again. It will fix the issue.
package com.devops.maven.cars_api_maven;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication (
exclude = {DataSourceAutoConfiguration.class },
scanBasePackages={
"com.devops.maven", "com.devop.application"}
)
public class CarsApplication {
public static void main(String[] args) {
SpringApplication.run(CarsApplication.class, args);
}
}
I am trying my hands at Hibernate Relation Mapping(OneToOne, etc) exercises using Spring Boot. Before you ask, I have already consulted this link : [https://stackoverflow.com/questions/11104897/hibernate-attempted-to-assign-id-from-null-one-to-one-property-employee]. I understand that the weak entity needs to have a ref to the parent entity, but I am not able to figure out, why I need to do that explicitly in Person class constructor?
The Codes are as follows.
SpringApplication:
package com.OneToOne.OneToOneMappingPractice;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class App
{
public static void main( String[] args )
{
ApplicationContext applContext = SpringApplication.run(App.class, args);
String[] beanNames = applContext.getBeanDefinitionNames();
Arrays.sort(beanNames);
for(String beanName : beanNames)
System.out.println(beanName);
}
}
CRUDController.java:
package com.OneToOne.OneToOneMappingPractice;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
#RestController
#CrossOrigin
public class CRUDController
{
private static int randomNumber=(int) Math.random();
#Autowired
private CRUDControllerRepository repository;
#GetMapping(value="/add")
public void add()
{
Person person = new Person("Person"+randomNumber, "Street"+randomNumber, randomNumber);
repository.save(person);
randomNumber+=1;
}
#GetMapping(value="/getAll")
public List<Person> getAll()
{
return repository.findAll();
}
#DeleteMapping(value="/deleteAll")
public void deleteAll()
{
repository.deleteAll();
}
}
Person.java:
package com.OneToOne.OneToOneMappingPractice;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
#Entity
public class Person
{
private String name;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private int Id;
#OneToOne(mappedBy="person", cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
private Address address;
public Person() {}
public Person(String name, String streetName, int house_number)
{
super();
this.name = name;
this.address=new Address();
this.address.setStreetName(streetName);
this.address.setHouse_number(house_number);
//this.address.setPerson(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java:
package com.OneToOne.OneToOneMappingPractice;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
#Entity
public class Address {
#Id
#Column(name="user_id")
private int Id;
private int house_number;
private String streetName;
#OneToOne
#MapsId
#JoinColumn(name = "user_id")
private Person person;
public Address(){}
public int getHouse_number() {
return house_number;
}
public void setHouse_number(int house_number) {
this.house_number = house_number;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
// public Person getPerson() {
// return person;
// }
public void setPerson(Person person) {
this.person = person;
}
}
CRUDControllerRepository.java:
package com.OneToOne.OneToOneMappingPractice;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional
public interface CRUDControllerRepository extends JpaRepository<Person, Integer>
{
Person save(Person person);
void deleteAll();
List<Person> findAll();
}
Following are my questions :
As you can see, in the Person class parameterized constructor, I have commented out the line : this.address.setPerson(this);. If I keep this line commented out, I get the exception : "attempted to assign id from null one-to-one property [com.OneToOne.OneToOneMappingPractice.Address.person]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.OneToOne.OneToOneMappingPractice.Address.person]". If I remove the comment syntax, it works perfectly. Why do I need to explicitly do this? Isn't the #OneToOne annotation supposed to take care of these references by itself?
2.If I enable the Person getPerson() method in the Address class, it recursively goes on, until the stack explodes: "Cannot render error page for request [/getAll] and exception [Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException".
Why cant Hibernate itself determine that it needs to stop at that boundary itself, instead of fetching the Parent Object again?
Am I missing something here about these mapping annotations, or anything else?
1- As you can see, in the Person class parameterized constructor, I
have commented out the line : this.address.setPerson(this);. If I keep
this line commented out, I get the exception : "attempted to assign id
from null one-to-one property
Hibernate will not set it explicitly because it does not know to which person this address belongs to you need to specify that explicitly.
The purpose of #OneToOne is to tell hibernate where to get the rest of the data when it is already mapped.
2.If I enable the Person getPerson() method in the Address class, it recursively goes on, until the stack explodes: "Cannot render error
page for request [/getAll] and exception [Could not write JSON:
Infinite recursion (StackOverflowError); nested exception is
com.fasterxml.jackson.databind.JsonMappingException". Why cant
Hibernate itself determine that it needs to stop at that boundary
itself, instead of fetching the Parent Object again?
The exception is caused by Jackson serializer and not from hibernate.
you can look at the examples here to see how it is fixed https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion.
I have a bunch of Car Objects. I'm able to render a list of all the Car Objects with each field being displayed on list.html. If I just wanted to display a list of make values on list.html, how would I go about that by using a query? Looking in Spring Data JPA Docs section 5.3.2, could I do something like findByAllMake();?
I've tried findByAllMake();...
The below code shows how I am successfully getting a complete list of all the objects. Looking to just get a list of all makes.
Car.java
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Car {
#Id
private String id;
private String make;
private String model;
private String year;
public Car() {
}
public Car(String id, String make, String model, String year) {
this.id = id;
this.make = make;
this.model = model;
this.year = year;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
CarController.java :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
#Controller
public class CarController {
#Autowired
private CarRepository carRepository;
#GetMapping("/list")
public String carMakeList(Model model){
model.addAttribute("list", carRepository.getAllMakes());
return "list";
}
}
CarRepository.java
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface CarRepository extends JpaRepository<Car, String> {
#Query(value="SELECT * FROM car;", nativeQuery=true)
List<Car> getAllMakes();
}
I've tried findByAllMake(); but I get back an Unsatisfactory Dependency error.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'carController': Unsatisfied dependency expressed through field 'carService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'carService': Unsatisfied dependency expressed through field 'carRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.example.demo.CarRepository.findAllByMake()! No parameter available for part make SIMPLE_PROPERTY (1): [Is, Equals] NEVER.
Makes are Strings. So if you want your method to return a list of makes, its return type should be List<String>, not List<Car>.
And the query needs to select makes, not cars:
select distinct car.make from Car car
Haven't run this on my laptop but what if you try:
to add constructor to CarController:
public CarController(CarRepository carRepository){
this.carRepository = carRepository;
}
And then probably just try:
public List<Car> findAll();
in the repository?
I am new to Boot-Spring apparently, I mostly copy some code from youtube on this case. However, after modification, in the end, I got a message like this;
APPLICATION FAILED TO START
Description:
Field postService in com.example.demo.BlogController required a bean of type 'Server.PostService' that could not be found.
Action:
Consider defining a bean of type 'Server.PostService' in your configuration.
.....Any idea how to deal with this situation. Thank you for the support.
1stclass-BlogApplciation-----com.example.demo(package)
2nd-Blog Controller--------same package as BlogApplication
3rdclass-Post---entities
4rthclass-PostRepositories---Repositories
**package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}**
**package com.example.demo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import Server.PostService;
import entities.Post;
import java.util.Date;
#RestController
public class BlogController {
#Autowired
private PostService postService;
#GetMapping(value="/")
public String index() {
return "index";
}
#GetMapping(value="/posts")
public List<Post>posts(){
return postService.getAllPosts();
}
#PostMapping(value="/post")
public void publishPost(#RequestBody Post post) {
if(post.getDatecreation() == null)
post.setDatecreation(new Date());
postService.insert(post);
}
}**
**package entities;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Post {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String title;
private String body;
private Date Datecreation;
public Post() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String gettitle() {
return title;
}
public void settitle(String title) {
this.title= title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Date getDatecreation() {
return Datecreation;
}
public void setDatecreation(Date datecreation) {
this.Datecreation = datecreation;
}
}**
**package Repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import entities.Post;
#Repository
public interface PostRepository extends JpaRepository<Post,Long>{
}**
Your BlogApplication Class, which is the class annotated with #SpringBootApplication is in the package com.example.demo. That means that, by default, Spring is going to launch a Component Scan starting from that package.
The problem is that your class PostService and your interface PostRepository are not in the same package as (or in a sub-package of) com.example.demo, so Spring can't find them and won't automatically create these beans for you.
To correct this issue, move the packages you created inside your root package (com.example.demo).
You can find more information about the use of #SpringBootApplication here.
EDIT:
You are missing PostService class or you have imported incorrect class as Server.PostService.
try to create a service like this one:
#Component
public class PostService {
public List<Post> getAllPosts(){
//your code
}
}
I am building a very simple Spring boot app with mvc + mongodb. I used Spring initializer to create the proj with web, thymeleaf and mongo dependencies. I have one controller, one model and a view but I keep on getting an error when trying to execute the app:
Description:
Field repo in com.example.CustomerController required a bean named 'mongoTemplate' that could not be found.
Action:
Consider defining a bean named 'mongoTemplate' in your configuration.
CustomerController:
import model.Customer;
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;
/**
* Created by Hello on 25/04/2017.
*/
#Controller
#RequestMapping("/home")
public class CustomerController {
#Autowired
CustomerMongoRepo repo;
#RequestMapping(value = "/home", method= RequestMethod.GET)
public String viewingHome(Model model){
//initDB();
model.addAttribute("key", "THIS IS FROM THE MODEL");
return "homepage";
}
}
CustomerMongoRepo:
import org.springframework.data.repository.CrudRepository;
import model.Customer;
public interface CustomerMongoRepo extends CrudRepository {}
MainApp:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
#SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class DemoApplication extends WebMvcAutoConfiguration {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Customer Model:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* Created by Hello on 25/04/2017.
*/
#Document(collection = "customerCollection")
public class Customer {
#Id
private int id;
private String fName;
private String sName;
public Customer(){}
public Customer(int id, String fName, String sName){
setfName(fName);
setsName(sName);
setId(id);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
}
My Application Properties:
spring.data.mongodb.database=customer
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.uri=mongodb://localhost:27018/mydb
spring.data.mongo.repositories.enabled=true
You are excluding Mongo Configuration.
#SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
Then how will spring create mongoTemplate for you. Remove this exclusion or create MongoTemplate manually and register it with application context(using #Bean)
I recently ran into this same problem and my solution was to remove spring-data-mongodb:
<!--<dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-mongodb</artifactId>-->
<!-- <version>3.2.1</version>-->
<!--</dependency>-->
and I kept spring-boot-starter-data-mongodb:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
It is seen that either the two together gave conflict or I need to add 'something' that I did not know.
Happy code !!! And I hope to be of help to you
Update
Later I found something related to what could be described by the problem although I would never finish checking it:
https://stackoverflow.com/a/12389842/7911776