Custom bean validation is not being called at all - java

I'm trying to create a custom bean validator, but, no matter what I do, the validator methods are not being called at all. All the other validation annotations are working perfectly.
This is the annotation:
package com.ats.boleta.validation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
#Target({ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = MaxDateValidator.class)
#Documented
public #interface MaxDate {
String message() default "Data está acima do máximo permitido.";
String string();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
This is the validator:
package com.ats.boleta.validation;
import java.time.LocalDate;
import java.time.temporal.Temporal;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* #author Haroldo de Oliveira Pinheiro
* #see https://gist.github.com/MottoX/e689adf41c22a531af4e18ce285690eb
*/
public class MaxDateValidator implements ConstraintValidator<MaxDate, Temporal> {
private LocalDate maxValue;
#Override
public void initialize(MaxDate constraintAnnotation) {
this.maxValue = LocalDate.parse(constraintAnnotation.string());
}
#Override
public boolean isValid(Temporal value, ConstraintValidatorContext context) {
return value == null || !LocalDate.from(value).isAfter(this.maxValue);
}
}
This is the main DTO that is being validated:
package com.ats.boleta.model.dto;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import com.ats.boleta.model.Boleto;
import com.ats.boleta.model.Cedente;
import com.ats.boleta.model.Titulo;
import com.ats.boleta.validation.PrefixConstraint;
import lombok.Data;
import lombok.ToString;
#Data
#ToString
public class BoletoDTO {
#NotBlank(message = "Nome não pode ficar em branco.")
private String nome;
#PrefixConstraint(message = "Cedente")
#NotNull(message = "Cedente não pode ficar em branco.")
private Cedente cedente;
#Valid
#NotEmpty(message = "Não foi informado nenhum título.")
private List<Titulo> titulo;
}
And this is the child DTO where #MaxDate is being used:
(...)
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Getter
#Setter
#ToString
public class Titulo {
#NotBlank(message = "Número do documento não pode ficar em branco.")
private String numeroDocumento = "";
private Integer nossoNumero;
#NotNull(message = "Carteira não pode ficar em branco.")
private Integer carteira;
private String valorDocumento = "";
#MaxDate(string = "2099-12-31", message = "Data de vencimento não pode ser posterior a 2099")
private LocalDate dataVencimento;
(...)
}
And this is the controller:
package com.ats.boleta.controller;
(...)
#Slf4j
#RestController
#RequestMapping("/v0/boleto")
public class BoletaController {
(...)
#RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> boleto(#Valid #RequestBody BoletoDTO dto) throws IOException {
(...)
}
#RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<InputStreamResource> remessa(#RequestBody BoletoDTO dto) throws IOException {
(...)
}
}
No matter what I do, neither MaxDateValidator.initialize(MaxDate) nor MaxDateValidator.isValid(Temporal, ConstraintValidatorContext) are called, no matter what. No exception is thrown, no warnings appear in the log, none of the aforementioned methods are called. All of the other annotations work as intended.
I have even tried to change the generic on MaxDateValidator to either LocalDate or even Object; nothing works.
What could be causing this behavior? Is there any way to debug it? Are there any Spring logs that could be activated to check what would be going wrong?

Can you please try to use:
#NotEmpty(message = "Não foi informado nenhum título.")
private List<#Valid Titulo> titulo;
Instead of:
#Valid
#NotEmpty(message = "Não foi informado nenhum título.")
private List<Titulo> titulo;
Please add annotation #Valid for method remessa
package com.ats.boleta.controller;
(...)
#Slf4j
#RestController
#RequestMapping("/v0/boleto")
public class BoletaController {
(...)
#RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> boleto(#Valid #RequestBody BoletoDTO dto) throws IOException {
(...)
}
#RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<InputStreamResource> remessa(#Valid #RequestBody BoletoDTO dto) throws IOException {
(...)
}
}

In the end, I had forgotten to add the #Valid annotation to the remessa() method on the controller:
package com.ats.boleta.controller;
(...)
#Slf4j
#RestController
#RequestMapping("/v0/boleto")
public class BoletaController {
(...)
#RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> boleto(#Valid #RequestBody BoletoDTO dto) throws IOException {
(...)
}
#RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<InputStreamResource> remessa(#Valid #RequestBody BoletoDTO dto) throws IOException {
(...)
}
}

Related

jakarta.servlet.ServletException, different behaviour between run, test and http request with SpringBoot API

I am building a SpringBoot API to learn the framework and I am facing two curious problems which probably are linked in some way.
First problem, when I try to test my code with my own Junit test class called EmployeeControllerTest, calling the method with http request returns the following error :
jakarta.servlet.ServletException: Request processing failed: java.util.NoSuchElementException: No value present
Second problem, when I perform those tests with Postman, the request /employees returning the list of employees works perfectly but the request /employee (with or without id added to the url), the API returns nothing.
In addition to this, calling the method from inside the code (in the run class) works great, I have every result I need.
Here are the code of every part involved. First the model class :
package com.openclassrooms.api.models;
import jakarta.persistence.*;
import lombok.Data;
#Data
#Entity
#Table(name = "employees")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
private String mail;
private String password;
}
The repository class :
package com.openclassrooms.api.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.openclassrooms.api.models.Employee;
#Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
The service class :
package com.openclassrooms.api.service;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.repository.EmployeeRepository;
#Service
public class EmployeeService {
#Autowired
private EmployeeRepository employeeRepository;
public Optional<Employee> getEmployee(final Long id) {
System.out.println("getEmployee ok");
return employeeRepository.findById(id);
}
public Iterable<Employee> getEmployees() {
System.out.println("getEmployees ok");
return employeeRepository.findAll();
}
public void deleteEmployee(final Long id) {
employeeRepository.deleteById(id);
}
public Employee saveEmployee(Employee employee) {
Employee savedEmployee = employeeRepository.save(employee);
return savedEmployee;
}
}
and the controller class :
package com.openclassrooms.api.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
#RestController
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
// Read - Get all employees
// #return - An Iterable object of Employee full filled
#GetMapping("/employees")
public Iterable<Employee> getEmployees() {
Iterable<Employee> list = employeeService.getEmployees();
System.out.println(list);
return list;
}
#GetMapping("/employee/{id}")
public Employee getEmployee(#PathVariable("id") final Long id) {
Optional<Employee> emp = employeeService.getEmployee(id);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
#GetMapping("/employee")
public Employee getEmployee() {
Optional<Employee> emp = employeeService.getEmployee(1L);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
}
Additionnaly, the main and test classes :
package com.openclassrooms.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
#SpringBootApplication
public class ApiApplication implements CommandLineRunner {
#Autowired
private EmployeeService employeeService;
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
public void run(String... args) throws Exception {
if (employeeService.getEmployee(1L).isPresent()) {
Employee emp1 = employeeService.getEmployee(1L).get();
System.out.println(emp1.getFirstName() + " " + emp1.getLastName());
} else {
System.out.println("Erreur, employé absent.");
}
System.out.println(employeeService.getEmployees());
}
}
package com.openclassrooms.api;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import java.io.PrintStream;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
//import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.ResultHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.openclassrooms.api.controller.EmployeeController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
//#SpringBootTest
//#AutoConfigureWebMvc
#WebMvcTest(controllers = EmployeeController.class)
public class EmployeeControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private EmployeeService employeeService;
#Test
public void testGetEmployees() throws Exception {
Employee response = new Employee();
mockMvc.perform(get("/employee"))
.andExpect(status().isOk())
.andDo(print(System.out))
.andExpect(jsonPath("$.firstName").value("Laurent"));
//.andExpect(jsonPath("$[0].firstName", is("Laurent")));
}
}
Thanks in advance for any answer !
EDIT : the SQL script used when building the database :
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250) NOT NULL,
last_name VARCHAR(250) NOT NULL,
mail VARCHAR(250) NOT NULL,
password VARCHAR(250) NOT NULL
)
INSERT INTO employees (first_name, last_name, mail, password) VALUES
('Laurent', 'GINA', 'laurentgina#mail.com', 'laurent'),
('Sophie', 'FONCEK', 'sophiefoncek#mail.com', 'sophie'),
('Agathe', 'FEELING', 'agathefeeling#mail.com', 'agathe');
There seems to be a couple of issues with the code.
First, in the getEmployee method of the EmployeeController class, the if condition checks if the Optional returned by the employeeService is empty, but if it's empty, the code returns null, which is not the desired behavior. Instead, you should check if the Optional is present, and if it is, return the value, otherwise return an appropriate response indicating that the employee was not found.
#GetMapping("/employee/{id}")
public Employee getEmployee(#PathVariable("id") final Long id) {
Optional<Employee> emp = employeeService.getEmployee(id);
if (emp.isPresent()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
// return an appropriate response indicating that the employee was not found
return null;
}
}
The same issue applies to the getEmployee method without a path variable.
#GetMapping("/employee")
public Employee getEmployee() {
Optional<Employee> emp = employeeService.getEmployee(1L);
if (emp.isPresent()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
// return an appropriate response indicating that the employee was not found
return null;
}
}
Regarding the issue with the Junit test class, it's difficult to determine the problem without more information, such as the exact error message or a code snippet of the test class.
Overall, the code needs to be more robust in handling cases where the employee was not found, and the test class needs to be further investigated to determine the root cause of the issue.

Not working lombok #NoArgsConstructor on a class?

Class where I create the empty constructor com lombok:
Notes.java:
package com.udacity.jwdnd.course1.cloudstorage.modelo;
import lombok.*;
import java.io.Serializable;
#Getter
#Setter
#NoArgsConstructor(access = AccessLevel.PUBLIC)
#AllArgsConstructor
public class Notes implements Serializable {
private Integer noteId;
private String noteTitle;
private String noteDescription;
private Integer userId;
public Notes(Integer noteId, String noteTitle
, String noteDescription, Integer userId) {
this.noteId = noteId;
this.noteTitle = noteTitle;
this.noteDescription = noteDescription;
this.userId = userId;
}
}
I use an object of Class Notes.java. In the following file an instance was created applying the empty constructor, but it throws me the error in the image:
import com.udacity.jwdnd.course1.cloudstorage.modelo.Notes;
import com.udacity.jwdnd.course1.cloudstorage.services.NoteService;
import com.udacity.jwdnd.course1.cloudstorage.services.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
#Controller
#RequestMapping("/home")
public class InicioController {
#Autowired
private UsersService usuarioService;
#Autowired
private NoteService notaService;
#Autowired
private CredentialService credencialService;
#Autowired
private ArchivoService archivoService;
#GetMapping()
public String irPaginaHome(Authentication auth, Model model){
model.addAttribute("noteForm", new Notes());
Integer idUsuario = usuarioService.obtenerIdusuario(auth.getName());
List<Notes> notas = notaService.notas(idUsuario);
model.addAttribute("notas",notas);
return "home";
}
}
model.addAttribute("noteForm", new Notes());
Can't find empty constructor, what would be the problem.

Error creating bean with name 'clienteController': Unsatisfied dependency expressed through field 'clienteService';

I'm trying to start my Spring Boot application but the error below is returning me:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clienteController': Unsatisfied dependency expressed through field 'clienteService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clienteService' defined in file [C:\Users\RenanFreitasDevenz\Documents\api-simulacao\target\classes\com\simulacao\api\services\ClienteService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clienteRepository' defined in com.simulacao.api.repository.ClienteRepository defined in #EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property buscarClientePorId found for type Cliente!
Class ClienteRepository:
package com.simulacao.api.repository;
import com.simulacao.api.documents.Cliente;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
#Repository
public interface ClienteRepository extends MongoRepository<Cliente, String> {
Cliente buscarClientePorId(String id);
Cliente buscarClientePorNome(String nome);
Optional<Cliente> buscarClientePorCpf(String cpf);
}
Class ClienteService:
package com.simulacao.api.services;
import com.simulacao.api.repository.ClienteRepository;
import com.simulacao.api.documents.Cliente;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
#Component
public class ClienteService {
#Autowired
private final ClienteRepository clienteRepository;
public ClienteService(ClienteRepository clienteRepository) {
this.clienteRepository = clienteRepository;
}
public List<Cliente> listarTodos() {
return this.clienteRepository.findAll();
}
public Cliente listarPorId(String id) {
return clienteRepository.buscarClientePorId(id);
}
public Cliente listarPorNome(String nome) {
return clienteRepository.buscarClientePorNome(nome);
}
public Cliente salvar(Cliente cliente) {
return this.clienteRepository.save(cliente);
}
public Cliente atualizar(Cliente cliente) {
return this.clienteRepository.save(cliente);
}
public Optional<Cliente> verificarCliente(String cpf) {
return this.clienteRepository.buscarClientePorCpf(cpf);
}
public void remover(String id) {
clienteRepository.deleteById(id);
}
}
Class ClienteController:
package com.simulacao.api.controller;
import com.simulacao.api.documents.Cliente;
import com.simulacao.api.documents.Transacao;
import com.simulacao.api.repository.ClienteRepository;
import com.simulacao.api.services.ClienteService;
import com.simulacao.api.services.ContaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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;
import java.util.List;
import java.util.Optional;
#RestController
#RequestMapping("api/clientes")
#Api(value = "API Rest Clientes")
#CrossOrigin(origins = "*")
public class ClienteController {
#Autowired
private ClienteService clienteService;
#Autowired
private ContaService contaService;
#Autowired
private ClienteRepository clienteRepository;
#GetMapping
#ApiOperation(value = "Retorna uma lista de clientes")
public ResponseEntity<List<Cliente>> listarTodos() {
return ResponseEntity.ok(this.clienteService.listarTodos());
}
#GetMapping("/{cpf}")
#ApiOperation(value = "Retorna os dados de um cliente")
public ResponseEntity<Cliente> dadosCliente(#PathVariable String cpf) {
Optional<Cliente> cliente = clienteRepository.buscarClientePorCpf(cpf);
return cliente.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
#PostMapping
#ApiOperation(value = "Salva um cliente")
#ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<Cliente> cadastrar(#Valid #RequestBody Cliente cliente) {
if (!clienteRepository.existsById(cliente.getCpf())) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(this.clienteService.salvar(cliente));
}
#PutMapping("depositar/{id}")
#ApiOperation(value = "Realiza um deposito na conta")
public ResponseEntity<?> depositar(#PathVariable double valor, #PathVariable String id){
this.contaService.depositar(valor);
return new ResponseEntity<>(HttpStatus.OK);
}
#PutMapping(path = "sacar/{id}")
#ApiOperation(value = "Realiza um saque na conta")
public ResponseEntity<?> sacar(#PathVariable double valor, #PathVariable String id) throws Exception {
if (valor <= 0) {
throw new Exception("valor incorreto");
}
this.contaService.sacar(valor);
return new ResponseEntity<>(HttpStatus.OK);
}
// Histórico de transações
#GetMapping(path = "extratoConta/{id}")
#ApiOperation(value = "Retorna uma lista de movimentações")
public ResponseEntity<?> extratoConta(#PathVariable String id){
List<Transacao> transacoes = contaService.extratoConta(id);
return new ResponseEntity<>(transacoes,HttpStatus.OK);
}
#DeleteMapping("/{clienteId}")
#ApiOperation(value = "Remove um cliente")
public ResponseEntity<Void> deletar(#PathVariable String clienteId) {
clienteService.remover(clienteId);
return ResponseEntity.noContent().build();
}
}
Class Cliente:
package com.simulacao.api.documents;
import lombok.*;
import org.hibernate.validator.constraints.br.CPF;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotEmpty;
#Document
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Component
public class Cliente {
#Id
private String id;
#NotEmpty(message = "Nome não pode ser vazio")
private String nome;
#Indexed(unique=true)
#CPF
private String cpf;
private Conta conta;
private boolean ativo;
}
What I tried to do but didn't fix:
1 - Annotate the main class with #ComponentScan ("com.simulacao.api")
2 - Note the class of service with #Service.
If you need me to post any more code snippets, let me know.
What can be done?
As I can see from your code that in your repository, you have method Cliente buscarClientePorId(String id); and similar methods.
You are using Query Methods and it must have something like findByFollowedByPropertyOfYourEntity.
According to the Spring Data Repository docs,
Spring Data JPA does a property check and traverses nested properties
Change your method according to this docs and it should work.
For instance, change your method inside the repository to
#Repository
public interface ClienteRepository extends MongoRepository<Cliente,
String> {
Cliente findById(String id);
}
I solved my problem.
I had to adapt the queries of the repository to:
findByParametro ...
Ex:
findBy "Property name"

Validation not performed in a Spring controller

I want to use annotations in classes. I use javax.validation.constrants.* for annotations.
public final class EmailCredential implements Serializable {
private static final long serialVersionUID = -1246534146345274432L;
#NotBlank(message = "Sender must not be empty.")
#Email
private final String sender;
#NotBlank(message = "Subject must not be empty.")
private final String subject;
/// getters setters
}
None of them are working as expected. Meaning that when a below API gets called, annotations should throw error if annotated field is invalid. It looks like there is no annotation to check fields. How properly can I use annotations in a normal class?
controller:
#PostMapping(value = "/email/credentials", consumes = MediaType.APPLICATION_JSON_VALUE)
public Map<String, Object> emailCredentials(#RequestBody EmailCredential emailCredential) {
return emailService.setCredentials(emailCredential);
}
In your case the validation has to be specified to be triggered.
So add the #Valid annotation on the parameter(s) that you want to validate such as :
import javax.validation.Valid;
// ...
#PostMapping(value = "/email/credentials", consumes = MediaType.APPLICATION_JSON_VALUE)
public Map<String, Object> emailCredentials(#RequestBody #Valid EmailCredential emailCredential) {
return emailService.setCredentials(emailCredential);
}
According to Spring Boot official documentation : Validating Form Input
You should indicate that your EmailCredential need to be validated using the annotation #Valid
Here's an example from documentation :
package hello;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Controller
public class WebController implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/results").setViewName("results");
}
#GetMapping("/")
public String showForm(PersonForm personForm) {
return "form";
}
#PostMapping("/")
public String checkPersonInfo(#Valid PersonForm personForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}
return "redirect:/results";
}
}

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': Injection of autowired dependencies failed

I have added some changes on a project that i am currently working on. I had a single User class and 3 different profiles (admin,docteur,patient).
I have changed the structure of the project by adding two User subclasses (Docteur and Patient) and the profiles are User or admin.
User:
package com.vivalio.springmvc.model;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.validator.constraints.NotEmpty;
#Entity
#Table(name = "USER")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#NotEmpty
#Column(name = "SSO_ID", unique = true, nullable = false)
private String ssoId;
#NotEmpty
#Column(name = "PASSWORD", nullable = false)
private String password;
#NotEmpty
#Column(name = "FIRST_NAME", nullable = false)
private String firstName;
#NotEmpty
#Column(name = "LAST_NAME", nullable = false)
private String lastName;
#NotEmpty
#Column(name = "EMAIL", nullable = false)
private String email;
#Column(name = "DTCREATION", nullable = true)
private String dateCreation;
#Column(name = "JJCREATION", nullable = true)
private String jjCreation;
public String getJjCreation() {
return jjCreation;
}
public void setJjCreation(String jjCreation) {
this.jjCreation = jjCreation;
}
#Column(name = "MMCREATION", nullable = true)
private String mmCreation;
public String getMmCreation() {
return mmCreation;
}
public void setMmCreation(String mmCreation) {
this.mmCreation = mmCreation;
}
#Column(name = "YYCREATION", nullable = true)
private String aaCreation;
public String getAaCreation() {
return aaCreation;
}
public void setAaCreation(String aaCreation) {
this.aaCreation = aaCreation;
}
public String getDateCreation() {
return dateCreation;
}
public void setDateCreation(String dateCreation) {
this.dateCreation = dateCreation;
}
#NotEmpty
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "USER_USER_PROFILE", joinColumns = { #JoinColumn(name = "USER_ID") }, inverseJoinColumns = {
#JoinColumn(name = "USER_PROFILE_ID") })
private Set<UserProfile> userProfiles = new HashSet<UserProfile>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSsoId() {
return ssoId;
}
public void setSsoId(String ssoId) {
this.ssoId = ssoId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Set<UserProfile> getUserProfiles() {
return userProfiles;
}
public void setUserProfiles(Set<UserProfile> userProfiles) {
this.userProfiles = userProfiles;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof User))
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (ssoId == null) {
if (other.ssoId != null)
return false;
} else if (!ssoId.equals(other.ssoId))
return false;
return true;
}
#Override
public String toString() {
return "User [id=" + id + ", ssoId=" + ssoId + ", password=" + password + ", firstName=" + firstName
+ ", lastName=" + lastName + ", email=" + email + "]";
}
}
Docteur:
package com.vivalio.springmvc.model;
import java.io.Serializable;
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.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "DOCTEUR")
public class Docteur extends User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(mappedBy = "doc")
private Set<Patient> patients = new HashSet<Patient>(0);
public Set<Patient> getPatients() {
return patients;
}
public void setPatients(Set<Patient> patients) {
this.patients = patients;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
Patient:
package com.vivalio.springmvc.model;
import java.io.Serializable;
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.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "PATIENT")
public class Patient extends User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(mappedBy = "patient")
private Set<Consultation> consultations = new HashSet<Consultation>(0);
#ManyToOne
#JoinColumn(name = "id")
private Docteur doc;
public Docteur getDoc() {
return doc;
}
public void setDoc(Docteur doc) {
this.doc = doc;
}
public Set<Consultation> getConsultations() {
return consultations;
}
public void setConsultations(Set<Consultation> consultations) {
this.consultations = consultations;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
Converter:
package com.vivalio.springmvc.converter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import com.vivalio.springmvc.model.UserProfile;
import com.vivalio.springmvc.service.UserProfileService;
/**
* A converter class used in views to map id's to actual userProfile objects.
*/
#Component
public class RoleToUserProfileConverter implements Converter<Object, UserProfile>{
static final Logger logger = LoggerFactory.getLogger(RoleToUserProfileConverter.class);
#Autowired
UserProfileService userProfileService;
/**
* Gets UserProfile by Id
* #see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
public UserProfile convert(Object element) {
Integer id = Integer.parseInt((String)element);
UserProfile profile= userProfileService.findById(id);
logger.info("Profile : {}",profile);
return profile;
}
}
Controller:
package com.vivalio.springmvc.controller;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.vivalio.springmvc.model.Consultation;
import com.vivalio.springmvc.model.User;
import com.vivalio.springmvc.model.UserProfile;
import com.vivalio.springmvc.model.UserProfileType;
import com.vivalio.springmvc.service.AppetitService;
import com.vivalio.springmvc.service.BouleService;
import com.vivalio.springmvc.service.ConsultationService;
import com.vivalio.springmvc.service.DocteurService;
import com.vivalio.springmvc.service.DouleurService;
import com.vivalio.springmvc.service.FaiblesseService;
import com.vivalio.springmvc.service.PatientService;
import com.vivalio.springmvc.service.UserProfileService;
import com.vivalio.springmvc.service.UserService;
import com.vivalio.springmvc.utils.Mail;
#Controller
#RequestMapping("/")
#SessionAttributes("roles")
public class AppController {
#Autowired
UserService userService;
#Autowired
UserProfileService userProfileService;
#Autowired
AppetitService appetitService;
#Autowired
FaiblesseService faiblesseService;
#Autowired
DouleurService douleurService;
#Autowired
BouleService bouleService;
#Autowired
MessageSource messageSource;
#Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
#Autowired
AuthenticationTrustResolver authenticationTrustResolver;
#Autowired
ConsultationService consultationService;
#Autowired
PatientService patientService;
#Autowired
DocteurService docteurServices;
/**
* This method will list all existing users.
*/
#RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET)
public String listUsers(ModelMap model) {
List<User> users = userService.findAllUsers();
model.addAttribute("users", users);
model.addAttribute("loggedinuser", getPrincipal());
return "userslist";
}
/**
* This method will provide the medium to add a new user.
*/
#RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", false);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/newconsultation" }, method = RequestMethod.GET)
public String newConsultation(ModelMap model) {
Consultation consultation = new Consultation();
model.addAttribute("consultation", consultation);
model.addAttribute("edit", false);
model.addAttribute("loggedinuser", getPrincipal());
return "registrationConsultation";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(#Valid User user, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
if (!userService.isUserSSOUnique(user.getId(), user.getSsoId())) {
FieldError ssoError = new FieldError("user", "ssoId", messageSource.getMessage("non.unique.ssoId",
new String[] { user.getSsoId() }, Locale.getDefault()));
result.addError(ssoError);
return "registration";
}
userService.saveUser(user);
Mail.sendMailRegistration("support#xxxxxxx.net", user.getEmail(), "xxxxxx#gmail.com",
"xxxxxx#gmail.com", "Creation de compte vivalio", "message");
model.addAttribute("success",
"User " + user.getFirstName() + " " + user.getLastName() + " registered successfully");
model.addAttribute("loggedinuser", getPrincipal());
// return "success";
return "redirect:/list";
}
/* ajouter la consultation du patient */
#RequestMapping(value = "/newconsultation", method = RequestMethod.POST)
public String saveConsultation(#Valid Consultation consultation, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "registrationConsultation";
}
// Patient patient = (Patient) getUser();
consultation.setPatient(null);
consultationService.saveConsultation(consultation);
if (consultation != null && consultation.getPatient() != null) {
Mail.sendMailAfterConsultation("support#xxxxxxx.net", consultation.getPatient().getEmail(),
"xxxxxx#gmail.com", "xxxxxxx#gmail.com", "Envoi de la consultation a votre medecin : ",
"Votre consultation REF-" + consultation.getId()
+ " a ete envoyee a votre medecin avec succes. Vous serez contacte en cas d'urgence.<br/>Ci dessous un recap de votre consultation :<br/>"
+ "<br/>Poid : " + consultation.getParam1() + "<br/>" + "Appetit :"
+ consultation.getParam2() + "<br/>" + "Faiblesse :" + consultation.getParam3() + "<br/>"
+ "Douleur :" + consultation.getParam4() + "<br/>" + "Boule :" + consultation.getParam5()
+ "<br/>" + "Fievre :" + consultation.getParam6() + "<br/>" + "Commentaire :"
+ consultation.getCommentaire() + "<br/>" + "<br/>L'equipe vivalio Group"
);
}
model.addAttribute("param1", consultation.getParam1());
model.addAttribute("param2", consultation.getParam2());
model.addAttribute("param3", consultation.getParam3());
model.addAttribute("param4", consultation.getParam4());
model.addAttribute("param5", consultation.getParam5());
model.addAttribute("param6", consultation.getParam6());
model.addAttribute("commentaire", consultation.getCommentaire());
return "redirect:/list";
}
/**
* This method will provide the medium to update an existing user.
*/
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.GET)
public String editUser(#PathVariable String ssoId, ModelMap model) {
User user = userService.findBySSO(ssoId);
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.POST)
public String updateUser(#Valid User user, BindingResult result, ModelMap model, #PathVariable String ssoId) {
if (result.hasErrors()) {
return "registration";
}
userService.updateUser(user);
Mail.sendMailRegistration("support#xxxxx.net", user.getEmail(), "xxxxxxxx#gmail.com",
"xxxxxxxx#gmail.com", "Modification des informations vivalio",
"Votre utilisateur vivalio a été modifié");
model.addAttribute("success",
"User " + user.getFirstName() + " " + user.getLastName() + " updated successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "redirect:/list";
}
/**
* This method will delete an user by it's SSOID value.
*/
#RequestMapping(value = { "/delete-user-{ssoId}" }, method = RequestMethod.GET)
public String deleteUser(#PathVariable String ssoId) {
userService.deleteUserBySSO(ssoId);
return "redirect:/list";
}
/**
* This method will provide UserProfile list to views
*/
#ModelAttribute("roles")
public List<UserProfile> initializeProfiles() {
return userProfileService.findAll();
}
/**
* This method will provide Docs list to views
*/
#ModelAttribute("docteurs")
public List<User> initializeAllDocs() {
return userService.findAllDocs();
}
/**
* This method will provide Appetit list to views
*/
#ModelAttribute("appetits")
public List<String> initializeAppetits() {
return appetitService.findAll();
}
/**
* This method will provide Faiblesse list to views
*/
#ModelAttribute("faiblesses")
public List<String> initializeFaiblesses() {
return faiblesseService.findAll();
}
/**
* This method will provide Douleur list to views
*/
#ModelAttribute("douleurs")
public List<String> initializeDouleurs() {
return douleurService.findAll();
}
/**
* This method will provide Boules list to views
*/
#ModelAttribute("boules")
public List<String> initializeBoules() {
return bouleService.findAll();
}
/**
* This method handles Access-Denied redirect.
*/
#RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
public String accessDeniedPage(ModelMap model) {
model.addAttribute("loggedinuser", getPrincipal());
return "accessDenied";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
if (isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:/list";
}
}
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logoutPage(HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
// new SecurityContextLogoutHandler().logout(request, response,
// auth);
persistentTokenBasedRememberMeServices.logout(request, response, auth);
SecurityContextHolder.getContext().setAuthentication(null);
}
return "redirect:/login?logout";
}
/**
* This method returns the principal[user-name] of logged-in user.
*/
private String getPrincipal() {
String userName = null;
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
userName = ((UserDetails) principal).getUsername();
} else {
userName = principal.toString();
}
return userName;
}
#SuppressWarnings("rawtypes")
private User getUser() {
String username = null;
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
username = ((UserDetails) principal).getUsername();
User usr = userService.findBySSO(username);
return usr;
}
/**
* This method returns true if users is already authenticated [logged-in],
* else false.
*/
private boolean isCurrentAuthenticationAnonymous() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authenticationTrustResolver.isAnonymous(authentication);
}
/**
* This method will redirect to dashboard
*/
#RequestMapping(value = { "/board" }, method = RequestMethod.GET)
public String tableauBord(ModelMap model, HttpSession session) {
List<User> users = userService.findAllUsers();
// TOTAL des utilisateurs de la base
int totalAdmin = userService.findAllAdmins().size();
int totalDocs = userService.findAllDocs().size();
int totalPatients = userService.findAllPatients().size();
// ANNEE COURANTE
int year = Calendar.getInstance().get(Calendar.YEAR);
StringBuilder sbyear = new StringBuilder();
sbyear.append(year);
// RECHERCHER LES COMPTES PAR TYPE DE L'ANNEE EN COURS
List<Object[]> totalComptesAdminParMois = userService
.findAllUsersByTypeAndyear(UserProfileType.ADMINISTRATEUR.getUserProfileType(), sbyear.toString());
List<Object[]> totalComptesDocParMois = userService
.findAllUsersByTypeAndyear(UserProfileType.ADMINISTRATEUR.getUserProfileType(), sbyear.toString());
List<Object[]> totalComptesPatParMois = userService
.findAllUsersByTypeAndyear(UserProfileType.UTILISATEUR.getUserProfileType(), sbyear.toString());
return "board";
}
}
I have the error in the message object when trying to restart the server.
AppConfig
package com.vivalio.springmvc.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import com.vivalio.springmvc.converter.RoleToUserProfileConverter;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.vivalio.springmvc")
public class AppConfig extends WebMvcConfigurerAdapter{
#Autowired
RoleToUserProfileConverter roleToUserProfileConverter;
/**
* Configure ViewResolvers to deliver preferred views.
*/
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
/**
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
/**
* Configure Converter to be used.
* In our example, we need a converter to convert string values[Roles] to UserProfiles in newUser.jsp
*/
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(roleToUserProfileConverter);
}
/**
* Configure MessageSource to lookup any validation/error message in internationalized property files
*/
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
/**Optional. It's only required when handling '.' in #PathVariables which otherwise ignore everything after last '.' in #PathVaidables argument.
* It's a known bug in Spring [https://jira.spring.io/browse/SPR-6164], still present in Spring 4.1.7.
* This is a workaround for this issue.
*/
#Override
public void configurePathMatch(PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
}
Stack trace
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'appConfig': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field:
com.vivalio.springmvc.converter.RoleToUserProfileConverter
com.vivalio.springmvc.configuration.AppConfig.roleToUserProfileConverter;
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'roleToUserProfileConverter': Injection of
autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: com.vivalio.springmvc.service.UserProfileService
com.vivalio.springmvc.converter.RoleToUserProfileConverter.userProfileService;
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'userProfileService': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: com.vivalio.springmvc.dao.UserProfileDao
com.vivalio.springmvc.service.UserProfileServiceImpl.dao; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'userProfileDao': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private org.hibernate.SessionFactory
com.vivalio.springmvc.dao.AbstractDao.sessionFactory; nested exception
is org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory' defined in class path
resource
[com/vivalio/springmvc/configuration/HibernateConfiguration.class]:
Invocation of init method failed; nested exception is
java.lang.ClassCastException:
org.hibernate.mapping.SingleTableSubclass cannot be cast to
org.hibernate.mapping.RootClass at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
That's the root cause of the exception:
org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass
Which means you have #Id in both child and parent classes.
Remove #Id field from both child classes, they will inherit it from the parent.
The second issue is that you have #JoinColumn with the same name as #Id
#ManyToOne
#JoinColumn(name = "doc_id") // give some unique column name here
private Docteur doc;
P.S. Little advice not related to the issue:
You have 10+ #Autowired dependencies in your Controller. It's really not a good way to design classes. Everytime observing too much #Autowired dependencies in one class should trigger you to think about you application design - this class takes too much responsibilities.

Categories

Resources