**
2021-11-26 20:30:57.375 WARN 11700 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookRestController': Unsatisfied dependency expressed through field 'bookService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookServiceImpl': Unsatisfied dependency expressed through field 'bookService'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'bookServiceImpl': Requested bean is currently in creation: Is there an unresolvable circular reference?
2021-11-26 20:30:57.376 INFO 11700 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-11-26 20:30:57.382 INFO 11700 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2021-11-26 20:30:57.393 INFO 11700 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2021-11-26 20:30:57.396 INFO 11700 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-11-26 20:30:57.410 INFO 11700 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-26 20:30:57.437 ERROR 11700 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter:
**
APPLICATION FAILED TO START
Description:
The dependencies of some of the beans in the application context form a cycle:
bookRestController (field private BookAuthorManyToManyRelationship.service.BookService BookAuthorManyToManyRelationship.Rest.BookRestController.bookService)
┌─────┐
| bookServiceImpl (field private BookAuthorManyToManyRelationship.service.BookService BookAuthorManyToManyRelationship.serviceImpl.BookServiceImpl.bookService)
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.*
BasicProjectApplication.java
```package BookAuthorManyToManyRelationship;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class BasicProjectApplication {
public static void main(String[] args) {
SpringApplication.run(BasicProjectApplication.class, args);
}
}```
**AuthorDAO.java**
```package BookAuthorManyToManyRelationship.dao;
import java.util.List;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
public interface AuthorDAO {
public Author findById(int id);
public List<Book> findListOfBookWrittenByAuthor();
public void deleteById(int id);
public void save(Author author);
}```
**BookDAO.java**
```package BookAuthorManyToManyRelationship.dao;
import java.util.List;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
public interface BookDAO {
public Book findById(int id);
public List<Author> findListOfAuthorWhoHasWrittenThisBook();
public void deleteById(int id);
public void save(Book book);
}```
**AuthorDAOImpl.java**
```package BookAuthorManyToManyRelationship.daoImpl;
import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import BookAuthorManyToManyRelationship.dao.AuthorDAO;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
#Repository
public class AuthorDAOImpl implements AuthorDAO {
#Autowired
private EntityManager entityManager;
#Override
public Author findById(int id) {
Session session = entityManager.unwrap(Session.class);
Author author = session.get(Author.class, id);
return author;
}
#Override
public List<Book> findListOfBookWrittenByAuthor() {
Session session = entityManager.unwrap(Session.class);
Query<Book> theQuery = session.createQuery("from Book",Book.class);
List<Book> book = theQuery.getResultList();
return book;
}
#Override
public void deleteById(int id) {
Session session = entityManager.unwrap(Session.class);
Query theQuery = session.createQuery("delete from Author where author_id=:theid");
theQuery.setParameter("theid", id);
theQuery.executeUpdate();
}
#Override
public void save(Author author) {
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(author);
}
}```
**BookDAOImpl.java**
```package BookAuthorManyToManyRelationship.daoImpl;
import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import BookAuthorManyToManyRelationship.dao.BookDAO;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
#Repository
public class BookDAOImpl implements BookDAO {
#Autowired
private EntityManager entityManager;
#Override
public Book findById(int id) {
Session session = entityManager.unwrap(Session.class);
Book b = session.get(Book.class, id);
return b;
}
#Override
public List<Author> findListOfAuthorWhoHasWrittenThisBook() {
Session session = entityManager.unwrap(Session.class);
Query<Author> q = session.createQuery("from Author",Author.class);
List<Author> author = q.getResultList();
return author;
}
#Override
public void deleteById(int id) {
Session session = entityManager.unwrap(Session.class);
Query q = session.createQuery("delete from Book where book_id:=theid");
q.setParameter("theid", id);
q.executeUpdate();
}
#Override
public void save(Book book) {
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(book);
}
}```
**Address.java**
```package BookAuthorManyToManyRelationship.entity;
import javax.persistence.Embeddable;
#Embeddable
public class Address {
String street;
String city;
String country;
public Address(String street, String city, String country) {
super();
this.street = street;
this.city = city;
this.country = country;
}
public Address() {
super();
// TODO Auto-generated constructor stub
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}```
**Author.java**
```package BookAuthorManyToManyRelationship.entity;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="author")
public class Author {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
String authorName;
Address address;
#ManyToMany(cascade = CascadeType.ALL)
List<Book> book;
public Author() {
super();
// TODO Auto-generated constructor stub
}
public Author(int id, String authorName,Address address,List<Book> book) {
super();
this.id = id;
this.authorName = authorName;
this.address = address;
this.book = book;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Book> getBook() {
return book;
}
public void setBook(List<Book> book) {
this.book = book;
}
}```
**Book.java**
```package BookAuthorManyToManyRelationship.entity;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="book")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
String book_name;
String subject;
#ManyToMany(cascade = CascadeType.ALL)
List<Author> author;
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Book(int id, String book_name, String subject, List<Author> author) {
super();
this.id = id;
this.book_name = book_name;
this.subject = subject;
this.author = author;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBook_name() {
return book_name;
}
public void setBook_name(String book_name) {
this.book_name = book_name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public List<Author> getAuthor() {
return author;
}
public void setAuthor(List<Author> author) {
this.author = author;
}
}```
**AuthorRestController**
```package BookAuthorManyToManyRelationship.Rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
import BookAuthorManyToManyRelationship.service.AuthorService;
#RestController
#RequestMapping("/welcome")
public class AuthorRestController {
#Autowired
private AuthorService authorService;
#GetMapping("/author/{id}")
public Author getAuthorById(#PathVariable int id )
{
return authorService.findById(id);
}
#GetMapping("/book")
public List<Book> getBook()
{
return authorService.findListOfBookWrittenByAuthor();
}
#PostMapping("/saveAuthor")
public void setAuthor(#RequestBody Author author)
{
authorService.save(author);
}
}```
**BookRestController.java**
```package BookAuthorManyToManyRelationship.Rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
import BookAuthorManyToManyRelationship.service.BookService;
#RestController
#RequestMapping("/abc")
public class BookRestController {
#Autowired
private BookService bookService;
#GetMapping("/book/{id}")
public Book getBookById(#PathVariable int id )
{
return bookService.findById(id);
}
#GetMapping("/author")
public List<Author> getAuthor()
{
return bookService.findListOfAuthorWhoHasWrittenThisBook();
}
#PostMapping("/saveBook")
public void setBook(#RequestBody Book book)
{
bookService.save(book);
}
}```
**AuthorService.java**
```package BookAuthorManyToManyRelationship.service;
import java.util.List;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
public interface AuthorService {
public Author findById(int id);
public List<Book> findListOfBookWrittenByAuthor();
public void deleteById(int id);
public void save(Author author);
}```
**BookService.java**
```package BookAuthorManyToManyRelationship.service;
import java.util.List;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
public interface BookService {
public Book findById(int id);
public List<Author> findListOfAuthorWhoHasWrittenThisBook();
public void deleteById(int id);
public void save(Book book);
}```
**AuthorServiceImpl.java**
```package BookAuthorManyToManyRelationship.serviceImpl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import BookAuthorManyToManyRelationship.dao.AuthorDAO;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
import BookAuthorManyToManyRelationship.service.AuthorService;
#Service
public class AuthorServiceImpl implements AuthorService {
#Autowired
private AuthorDAO authorDAO;
#Override
#Transactional
public Author findById(int id) {
return authorDAO.findById(id);
}
#Override
#Transactional
public List<Book> findListOfBookWrittenByAuthor() {
return authorDAO.findListOfBookWrittenByAuthor();
}
#Override
#Transactional
public void deleteById(int id) {
authorDAO.deleteById(id);
}
#Override
#Transactional
public void save(Author author) {
authorDAO.save(author);
}
}```
**BookServiceImpl.java**
```package BookAuthorManyToManyRelationship.serviceImpl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import BookAuthorManyToManyRelationship.entity.Author;
import BookAuthorManyToManyRelationship.entity.Book;
import BookAuthorManyToManyRelationship.service.BookService;
#Service
public class BookServiceImpl implements BookService {
#Autowired
private BookService bookService;
#Override
#Transactional
public Book findById(int id) {
return bookService.findById(id);
}
#Override
#Transactional
public List<Author> findListOfAuthorWhoHasWrittenThisBook() {
return bookService.findListOfAuthorWhoHasWrittenThisBook();
}
#Override
#Transactional
public void deleteById(int id) {
bookService.deleteById(id);
}
#Override
#Transactional
public void save(Book book) {
bookService.save(book);
}
}
```
here is cause of your problem
#Service
public class BookServiceImpl implements BookService {
#Autowired
private BookService bookService
I am not able to understand why do you have reference of BookService inside it's own implementation, my best guess you wanted to add BookDAO here.
Related
I'm trying to do a simple CRUD in postgres with spring, but for no reason my IoD mechanism doesn't work and throws an error like this:
Description:
Parameter 0 of constructor in br.com.maptriz.formulario_dinamico.service.FormularioDinamicoService required a bean of type 'br.com.maptriz.formulario_dinamico.repository.FormularioDinamicoRepository' that could not be found.
Action:
Consider defining a bean of type 'br.com.maptriz.formulario_dinamico.repository.FormularioDinamicoRepository' in your configuration.
Here's my code:
FormularioDinamicoApplication.java
package br.com.maptriz.formulario_dinamico;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// #EnableJpaRepositories("br.com.maptriz.formulario_dinamico.repository")
// #EnableScheduling
// #EnableDiscoveryClient
// #ComponentScan
#SpringBootApplication
public class FormularioDinamicoApplication {
public static void main(String[] args) {
SpringApplication.run(FormularioDinamicoApplication.class, args);
}
}
FormularioDinamico
package br.com.maptriz.formulario_dinamico.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "formulario_dinamico")
public class FormularioDinamico {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name="tipo_tabela")
private Long tabelaId;
private String name;
private String campos;
protected FormularioDinamico() {}
public FormularioDinamico(Long tabelaId, String name, String campos) {
this.tabelaId = tabelaId;
this.name = name;
this.campos = campos;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTabelaId() {
return this.tabelaId;
}
public void setTabelaId(Long tabelaId) {
this.tabelaId = tabelaId;
}
public String getName() {
return this.name;
}
public void setObservacao(String name) {
this.name = name;
}
public String getCampos() {
return this.campos;
}
public void setCampos(String campos) {
this.campos = campos;
}
#Override
public String toString() {
return "EntidadeGenerica{" +
"id=" + id +
", dataAtualizacao=" + tabelaId +
", dataCadastro=" + name +
", observacao='" + campos + '}';
}
}
FormlarioDinamicoController.java
package br.com.maptriz.formulario_dinamico.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.maptriz.formulario_dinamico.model.FormularioDinamico;
import br.com.maptriz.formulario_dinamico.service.FormularioDinamicoService;
#RestController
#RequestMapping
public class FormularioDinamicoController {
private final FormularioDinamicoService service;
#Autowired
public FormularioDinamicoController(FormularioDinamicoService service) {
this.service = service;
}
// #GetMapping
// public List<DynamicForm> getDynamicForm() {
// return dynamicFormService.getDynamicForm();
// }
#PostMapping("/create")
public void registrarNovoFormularioDinamico(#RequestBody FormularioDinamico formularioDinamico) {
System.out.println("TEST");
service.adicionarNovoFormularioDinamico(formularioDinamico);
}
}
FormularioDinamicoService.java
package br.com.maptriz.formulario_dinamico.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import br.com.maptriz.formulario_dinamico.model.FormularioDinamico;
import br.com.maptriz.formulario_dinamico.repository.FormularioDinamicoRepository;
#Service
public class FormularioDinamicoService {
private final FormularioDinamicoRepository repository;
#Autowired
public FormularioDinamicoService(FormularioDinamicoRepository repository) {
this.repository = repository;
}
// public List<DynamicForm> getDynamicForm() {
// return dynamicFormRepository.findAll();
// }
public void adicionarNovoFormularioDinamico(FormularioDinamico formularioDinamico) {
List<FormularioDinamico> topicos = repository.findAll();
System.out.println("HEREEEE");
System.out.println(topicos);
}
}
And finally FormularioDinamicoRepository.java
package br.com.maptriz.formulario_dinamico.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import br.com.maptriz.formulario_dinamico.model.FormularioDinamico;
public interface FormularioDinamicoRepository
extends JpaRepository<FormularioDinamico, Long> {
List<FormularioDinamico> findAll();
}
My Folder Structure:
src
main
java/br/com/maptriz/formulario_dinamico
controller
model
repository
service
FormularioDinamicoApplication.java
Add #Repository annotation on the interface FormularioDinamicoRepository. It should be working seamlessly.
The moment you add it spring identifies it as a bean and creates an object and injects the bean wherever autowired.
I tried making a simple REST API using Spring Boot. I have put the classes in separate packages. In this case, the URL mapping is not working (checked using Postman), whereas its working fine if I put them all in the same package as that of the main class.
""" Hierarchy of the packages :
com.example.ProductCRUD
|-----ProductCrudApplication.java (main)
com.example.ProductCRUD.Controller
|-----ProductController.java(controller)
com.example.ProductCRUD.Entity
|------Product.java(model class)
com.example.Repository
|-----ProductRepo.java(Repository interface)
com.example.Service
|-------ProductService.java(Service class) """
I tried including #componentscan("com.example") in the main class. But in that case, it throws an error.
If somebody could help me in finding out where I went wrong, it would be helpful.
Thanks in advance for your help.
//PRODUCT MODEL CLASS (Product.java)
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
//MODEL CLASS
#Entity
public class Product {
#Id
#GeneratedValue
private int id;
private String name;
private int quantity;
private int price;
public Product() {
super();
// TODO Auto-generated constructor stub
}
public Product(int id, String name, int quantity, int price) {
super();
this.id = id;
this.name = name;
this.quantity = quantity;
this.price = 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 int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
//Repository (ProductRepo.java) :interface
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.Entity.Product;
public interface ProductRepo extends JpaRepository<Product,Integer> {
Product findByName(String name);
}
//Service class(ProductService.java)
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.Entity.Product;
import com.example.Repository.ProductRepo;
#Service
public class ProductService {
#Autowired
private ProductRepo repo; //service--> repository
//PUT
public Product create(Product product) {
Product p=repo.save(product); //default method of JPA to make the data persist in the DB
return p;
}
public List<Product> createproducts(List<Product> products) {
List<Product> p=repo.saveAll(products);
return p;
}
//GET
public List<Product> getProducts(){
List<Product> p=repo.findAll();
return p;
}
public Product getProductByid(int id){
Product p=repo.findById(id).orElse(null); //return id , if id not found then return null
return p;
}
public Product getProductByName(String name){
Product p=repo.findByName(name); //customized method in JPA (declared in the interface)
return p;
}
//DELETE
public String deleteProduct(int id) {
repo.deleteById(id);
return "Product removed : "+id;
}
//UPDATE
public Product updateProduct(Product product) {
Product existing=repo.findById(product.getId()).orElse(null);
existing.setName(product.getName());
existing.setPrice(product.getPrice());
existing.setQuantity(product.getQuantity());
Product p=repo.save(existing);
return p;
}
}
//Controller class (ProductController.java)
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import com.example.Entity.Product;
import com.example.Service.ProductService;
#RestController
public class ProductController {
#Autowired
private ProductService service; //controller --> service
#PostMapping("/create")
public Product addProduct(#RequestBody Product product) {
return service.create(product);
}
#PostMapping("/createProducts")
public List<Product> addProducts(#RequestBody List<Product> products) {
return service.createproducts(products);
}
#GetMapping("/getproducts/{id}")
public Product getProductById(#PathVariable int id){
return service.getProductByid(id);
}
#GetMapping("/getproducts/{name}")
public Product getProductByName(#PathVariable String name){
return service.getProductByName(name);
}
#GetMapping("/getproducts")
public List<Product> getProducts(){
return service.getProducts();
}
#DeleteMapping("/delete/{id}")
public String delete(#PathVariable int id) {
return service.deleteProduct(id);
}
#PutMapping("/update/{id}")
public Product update(#RequestBody Product product) {
return service.updateProduct(product);
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#ComponentScan("com.example")
public class ProductCrudApplication {
public static void main(String[] args) {
SpringApplication.run(ProductCrudApplication.class, args);
}
}
-- If I include the #Componentscan this is the error I am receiving :
Field repo in com.example.Service.ProductService required a bean of type 'com.example.Repository.ProductRepo' 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.example.Repository.ProductRepo' in your configuration.
moving the main class from
com/example/ProductCRUD
to
com/example
fixes your issue.
diff:
rename from ProductCRUD/src/main/java/com/example/ProductCRUD/ProductCrudApplication.java
rename to ProductCRUD/src/main/java/com/example/ProductCrudApplication.java
index 1633cbf..93294a2 100644
--- a/ProductCRUD/src/main/java/com/example/ProductCRUD/ProductCrudApplication.java
+++ b/ProductCRUD/src/main/java/com/example/ProductCrudApplication.java
## -1,4 +1,4 ##
-package com.example.ProductCRUD;
+package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
I have developped a Spring boot application that was using fetch = EAGER annotation on all relationships between entities. I think this is causing severe performance issues and I've since learned that it is seemingly an anti-pattern (https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ & https://vladmihalcea.com/eager-fetching-is-a-code-smell/).
I've been trying to figure out how to use lazy loading properly. I've come up with a minimal example that allows me to reproduce it.
TestJpaApplication
package com.myproject.testJpa;
import com.myproject.testJpa.entity.Host;
import com.myproject.testJpa.entity.HostSet;
import com.myproject.testJpa.entity.repository.HostRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.myproject.testJpa.entity.repository.HostSetRepository;
import org.springframework.transaction.annotation.Transactional;
#SpringBootApplication
public class TestJpaApplication {
private final Logger logger = LoggerFactory.getLogger(TestJpaApplication.class);
#Autowired
private HostRepository hostRepository;
#Autowired
private HostSetRepository hostSetRepository;
public static void main(String[] args) {
SpringApplication.run(TestJpaApplication.class, args);
}
#Bean
public CommandLineRunner demo() {
return (args) -> {
init();
fetch();
};
}
private void init() {
Host host1 = findOrCreateHost("HOST 1");
Host host2 = findOrCreateHost("HOST 2");
Host host3 = findOrCreateHost("HOST 3");
HostSet hostSet = findOrCreateHostSet("HOST SET 1");
hostSet.addHost(host1);
hostSetRepository.save(hostSet);
hostRepository.save(host1);
hostRepository.save(host2);
hostRepository.save(host3);
}
#Transactional
private void fetch() {
HostSet hostSet = hostSetRepository.findOneByNameIgnoreCase("HOST SET 1");
for(Host host : hostSet.getHosts()) {
logger.debug("Host: {}", host);
}
}
public Host findOrCreateHost(String name) {
Host host = hostRepository.findOneByNameIgnoreCase(name);
if(host == null) {
host = new Host(name);
hostRepository.save(host);
}
return host;
}
public HostSet findOrCreateHostSet(String name) {
HostSet hostSet = hostSetRepository.findOneByNameIgnoreCase(name);
if (hostSet == null) {
hostSet = new HostSet(name);
hostSetRepository.save(hostSet);
}
logger.debug("Host: {}", hostSet.getHosts());
return hostSet;
}
}
Host
package com.myproject.testJpa.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
#Entity
public class Host {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "host__id")
private Long id;
private String name;
#ManyToMany(mappedBy = "hosts")
private Set<HostSet> hostSets = new HashSet<>();
public Host() {
}
public Host(Long id) {
this.id = id;
}
public Host(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<HostSet> getHostSets() {
return hostSets;
}
public void setHostSets(Set<HostSet> hostSets) {
this.hostSets = hostSets;
hostSets.forEach(hs -> addToHostSet(hs));
}
public Host addToHostSet(HostSet hostSet) {
if (!hostSets.contains(hostSet)) {
hostSets.add(hostSet);
hostSet.getHosts().add(this);
}
return this;
}
public Host removeFromHostSet(HostSet hostSet) {
if (hostSets.contains(hostSet)) {
hostSets.remove(hostSet);
hostSet.getHosts().remove(this);
}
return this;
}
}
HostSet
package com.myproject.testJpa.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
#Entity
public class HostSet {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "host_set__id")
private Long id;
private String name;
#ManyToMany
#JoinTable(
name = "host_set__host",
joinColumns = #JoinColumn(name = "host_set__id"),
inverseJoinColumns = #JoinColumn(name = "host__id")
)
private Set<Host> hosts = new HashSet<>();
public HostSet() {
}
public HostSet(Long id) {
this.id = id;
}
public HostSet(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Host> getHosts() {
return hosts;
}
public void setHosts(Set<Host> hosts) {
this.hosts = hosts;
}
public HostSet addHost(Host host) {
if(!hosts.contains(host)) {
hosts.add(host);
host.addToHostSet(this);
}
return this;
}
public HostSet removeHost(Host host) {
if(hosts.contains(host)) {
hosts.remove(host);
host.removeFromHostSet(this);
}
return this;
}
}
HostRepository
package com.myproject.testJpa.entity.repository;
import com.myproject.testJpa.entity.Host;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface HostRepository extends JpaRepository<Host, Long> {
public Host findOneByNameIgnoreCase(String name);
}
HostSetRepository
package com.myproject.testJpa.entity.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.myproject.testJpa.entity.HostSet;
#Repository
public interface HostSetRepository extends JpaRepository<HostSet, Long> {
public HostSet findOneByNameIgnoreCase(String name);
}
When I run the application, it throws the following error when looping over the hosts of the retrieved hostSet in the fetch() method.
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.myproject.testJpa.entity.HostSet.hosts, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:188)
at com.myproject.testJpa.TestJpaApplication.fetch(TestJpaApplication.java:58)
at com.myproject.testJpa.TestJpaApplication.lambda$demo$0(TestJpaApplication.java:34)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784)
I've tried adding the #Transactional annotation in several places but to no avail. It's driving me crazy because I don't see what I'm doing wrong.
Thanks for your help!
It turns out that the #Transactional was not working in the TestJpaApplication class (I did not set it on the anonymous method, don't know how or if it's possible).
I moved the content to a separate service and it worked.
I am building simple ManyToOne relationship using spring JAP. i get UnsatisfiedDependencyException Error with bean name Unsatisfied dependency expressed through field
UnsatisfiedDependencyException: Error creating bean with name 'procjectController': Unsatisfied
Here is my file.
project.java
package com.ganesh.dto;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
public class Project {
#Id
private int projectId;
private String projectName;
//Relation establish
#ManyToOne(
fetch = FetchType.LAZY,
optional = false
)
#JoinColumn(
name = "employee_id",
nullable = false
)
#JsonIgnore
private Employee employee;
public Project() {
}
public Project(int projectId, String projectName, int eId) {
super();
this.projectId = projectId;
this.projectName = projectName;
//Adding employee
this.employee = new Employee(eId,"","");
}
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
//Adding getter and setters Employee reference
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
ProjectDao.java
package com.ganesh.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.ganesh.dto.Project;
#Repository
public interface ProjectDao extends JpaRepository<Project, Integer> {
List<Project> findEmployeeById(int eId);
}
ImpProjectService.java
package com.ganesh.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ganesh.dao.*;
import com.ganesh.dto.Project;
#Service
public class ImpProjectService implements ProjectService {
#Autowired
private ProjectDao projectDao;
#Override
public List<Project> getProjectList(int eId) {
System.out.println("in Dao class employee id"+ eId);
return projectDao.findEmployeeById(eId);
}
#Override
public Project getProjectById(int id) {
return projectDao.getOne(id);
}
#Override
public void addProject(Project project) {
projectDao.save(project);
}
#Override
public void updateProject(Project project) {
projectDao.save(project);
}
#Override
public void deleteProjectById(int id) {
projectDao.deleteById(id);
}
#Override
public List<Project> getAllProject() {
return projectDao.findAll();
}
}
ProcjectController.java
package com.ganesh.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.ganesh.dto.*;
import com.ganesh.service.*;
#RestController
public class ProcjectController {
#Autowired
private ImpProjectService projectService;
#RequestMapping("/projects")
public List<Project> getProjectList(){
return projectService.getAllProject();
}
#RequestMapping("/employees/{eId}/projects")
public List<Project> getAllProjects(#PathVariable int eId){
System.out.println("In Project Controller");
List<Project> projList = projectService.getProjectList(eId);
System.out.println(projList);
return projList;
}
#RequestMapping("/employees/{eId}/projects/{id}")
public Project getProjectById(#PathVariable int id) {
return projectService.getProjectById(id);
}
#RequestMapping(method = RequestMethod.POST, value="/employees/{eId}/projects")
public void addProject(#RequestBody Project project, #PathVariable int eId) {
project.setEmployee(new Employee(eId,"",""));
projectService.addProject(project);
}
#RequestMapping(method = RequestMethod.PUT, value="/employees/{eId}/projects/{id}")
public void updateProject(#RequestBody Project project, #PathVariable int eId) {
project.setEmployee(new Employee(eId,"",""));
projectService.updateProject(project);
}
#RequestMapping(method = RequestMethod.DELETE, value="/projects/{id}")
public void deleteProjecstById(#PathVariable int id) {
projectService.deleteProjectById(id);
}
}
Note: This answer is based on insufficient data, because stack trace is not available. With correct and complete stacktrace, we might be able to provide more precise answer.
Answer:
Looks like a problem in your Dao class.
You have written
#Repository
public interface ProjectDao extends JpaRepository<Project, Integer> {
List<Project> findEmployeeById(int eId);
}
Which means you are creating a repository of type Project and trying to fire a query as findEmployeeById, It should either be findByEmployee, which accepts Employee as a parameter, or should not be there in place at all. Because the query syntax and the Template parameters do not match. So Spring will not be able to initialize the query handlers for the same.
Try changing it as below, if is satisfies your purpose.
#Repository
public interface ProjectDao extends JpaRepository {
List<Project> findAllByEmployee(Employee emp);
}
Please check the same, and correct. If it still doesn't work, please post the full stack trace, and we can help you out.
I went to develop an application to manage students in a university, I am looking for how to find students in relation to a date entered for that I have developed the following code lines:
1- Model student.java
package com.avatar.model;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.JoinColumn;
#Entity
#Table(name = "Students")
public class Student{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String nom;
private String prenom;
private String numTel;
private String mail;
#Temporal(TemporalType.DATE)
private Date dateCurrent;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "student_techno",
joinColumns = { #JoinColumn(name = "student_id") },
inverseJoinColumns = { #JoinColumn(name = "techno_id") })
private Set<Techno> techno = new HashSet<>();
public Student() {
}
#SuppressWarnings("unchecked")
public Student(String nom, String prenom,String numTel, String mail, Date dateCurrent,
) {
super();
this.nom = nom;
this.prenom = prenom;
this.numTel = numTel;
this.mail = mail;
this.dateCurrent = dateCurrent;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNumTel() {
return numTel;
}
public void setNumTel(String numTel) {
this.numTel = numTel;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getdateCurrent() {
return dateCurrent;
}
public void setdateCurrent(Date dateCurrent) {
this.dateCurrent = dateCurrent;
}
#Override
public String toString() {
return "Student[nom=" + nom + ", prenom=" + prenom + ", numTel=" + numTel + ", mail="
+ mail + ", dateCurrent=" + dateCurrent+ "]";
}
}
2- Controller
package com.avatar.web;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.avatar.dao.StudentDao;
import com.avatar.model.Student;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
#RequestMapping("/avatar")
public class StudentController {
#Autowired
StudentDao studentdao;
#GetMapping(value = "/all-students")
public List<Student> listeDesStudent() {
List<Student> students= studentdao.findAll();
if (students.isEmpty())
throw new ProductNotFoundException("No student is registered in the database");
return students;
}
#GetMapping(value = "/all-students/dateCurrent/{dateCurrent}")
public List<Student> viewStudent(#PathVariable("dateCurrent") #DateTimeFormat(pattern = "yyyy-MM-dd") Date dateCurrent) {
Calendar c = Calendar.getInstance();
c.setTime(dateCurrent);
c.add(Calendar.DATE, 1);
dateCurrent = c.getTime();
return studentdao.findByDate(dateCurrent);
}
#GetMapping(value = "/all-students /techno/{nomTechno}")
List<Student > viewStudent(#PathVariable("nomTechno") String nomTechno) {
return studentdao.findDistinctByTechnoNomTechno(nomTechno);
}
#PostMapping(value = "/add-student")
public Student addStudent(#RequestBody Student student) {
Student studentAdded= studentdao.save(Student);
return studentAdded;
}
}
3- DAO
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDate(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
4- applications.properties
server.port= 8080
# MySQL Properties
spring.jpa.show-sql = true
spring.datasource.url= jdbc:mysql://localhost:3306/avatar?serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=*****
spring.datasource.password=*****
# Hibernate Properties
spring.jpa.hibernate.ddl-auto=update
in my console i have:
Failed to create query for method public abstract java.util.List com.avatar.dao.StudentDao.findByDate(java.util.Date)! No property date found for type Student!
Please update DAO as per for below mentioned changes
If the field name is dateCurrent then findByDateCurrent.
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDateCurrent(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
You are missing field name, in Entity class it is not the date by dateCurrent, thus your JPA should be findByDateCurrent