5
respostas

Problema com o scanner

Aparentemente tudo está funcionando no meu código porem quando tento salvar um novo item em qualquer uma das tabelas usando o scanner para capturar a string no console se eu uso um espaço recebo as exceções "java.lang.IllegalStateException: Failed to execute CommandLineRunner" -> "Caused by: java.util.InputMismatchException: null"

Por exemplo se eu digito algo como "desenvolvedor java" na coluna de descrição da tabela de cargos assim que aperto enter recebo essas exceções e quando vou verificar no banco de dados o cargo foi salvo como "desenvolvedor" ou seja tudo antes do espaço é salvo mas por algum motivo o espaço esta quebrando o scanner, oque não estava acontecendo antes da implementação de Funcionarios e Unidades.

5 respostas

Oi João

Como está o código na parte do scanner?

Esse é o código da aplicação spring onde o scanner é instanciado

package br.com.alura.spring.data;

import java.util.Scanner;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import br.com.alura.spring.data.service.CrudCargoService;
import br.com.alura.spring.data.service.CrudFuncionarioService;
import br.com.alura.spring.data.service.CrudUnidadeService;
import br.com.alura.spring.data.service.RelatorioFuncionarioDinamico;
import br.com.alura.spring.data.service.RelatoriosService;

@EnableJpaRepositories
@SpringBootApplication
public class SpringDataApplication implements CommandLineRunner {

    private final CrudCargoService cargoService;
    private final CrudFuncionarioService funcionarioService;
    private final CrudUnidadeService unidadeService;
    private final RelatoriosService relatoriosService;
    private final RelatorioFuncionarioDinamico relatorioFuncionarioDinamico;

    private Boolean system = true;

    public SpringDataApplication(CrudCargoService cargoService, CrudFuncionarioService funcionarioService,
            CrudUnidadeService unidadeService, RelatoriosService relatoriosService,
            RelatorioFuncionarioDinamico relatorioFuncionarioDinamico) {
        this.cargoService = cargoService;
        this.funcionarioService = funcionarioService;
        this.unidadeService = unidadeService;
        this.relatoriosService = relatoriosService;
        this.relatorioFuncionarioDinamico = relatorioFuncionarioDinamico;
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringDataApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Scanner scanner = new Scanner(System.in);

        while (system) {
            System.out.println("Qual tabela deseja acessar? ");
            System.out.println("0 - Sair");
            System.out.println("1 - Cargo");
            System.out.println("2 - Funcionario");
            System.out.println("3 - Unidade");
            System.out.println("4 - Relatorios");
            System.out.println("5 - Relatorio Dinamico");

            int action = scanner.nextInt();

            switch (action) {
            case 1:
                cargoService.inicial(scanner);
                break;
            case 2:
                funcionarioService.inicial(scanner);
                break;
            case 3:
                unidadeService.inicial(scanner);
                break;
            case 4:
                relatoriosService.inicial(scanner);
                break;
            case 5:
                relatorioFuncionarioDinamico.inicial(scanner);
                break;
            default:
                System.out.println("Finalizando");
                system = false;
                break;
            }

        }
        scanner.close();
    }

}

Esse é um dos services que utiliza o scanner pra capturar a informação do console

package br.com.alura.spring.data.service;

import java.util.Scanner;

import org.springframework.stereotype.Service;

import br.com.alura.spring.data.orm.Cargo;
import br.com.alura.spring.data.repository.CargoRepository;

@Service
public class CrudCargoService {

    private Boolean system = true;
    private final CargoRepository cargoRepository;

    public CrudCargoService(CargoRepository cargoRepository) {
        this.cargoRepository = cargoRepository;
    }

    public void inicial(Scanner scanner) {

        while (system) {
            System.out.println("Qual acao deseja executar?");
            System.out.println("0 - Sair");
            System.out.println("1 - Visualizar");
            System.out.println("2 - Salvar");
            System.out.println("3 - Atualizar");
            System.out.println("4 - Deletar");

            int action = scanner.nextInt();

            switch (action) {
            case 0:
                system = false;
                break;

            case 1:
                visualizar(scanner);
                break;

            case 2:
                salvar(scanner);
                break;

            case 3:
                atualizar(scanner);
                break;

            case 4:
                deletar(scanner);
                break;

            default:
                system = false;
                break;
            }
        }

    }

    public void salvar(Scanner scanner) {
        System.out.println("Digite a descricao do cargo");
        String descricao = scanner.next();
        Cargo cargo = new Cargo();
        cargo.setDescricao(descricao);
        cargoRepository.save(cargo);
        System.out.println("Item Salvo");
    }

    private void atualizar(Scanner scanner) {
        System.out.println("Qual o id do item que será atualizado?");
        int id = scanner.nextInt();
        System.out.println("Descricao do cargo");
        String descricao = scanner.next();
        Cargo cargo = new Cargo();
        cargo.setId(id);
        cargo.setDescricao(descricao);
        cargoRepository.save(cargo);
        System.out.println("Item Atualizado");
    }

    private void deletar(Scanner scanner) {
        System.out.println("Qual o id do item a ser DELETADO?");
        int id = scanner.nextInt();
        System.out.println("Certeza que deseja deletar o item " + cargoRepository.findById(id));
        System.out.println("0 - NAO");
        System.out.println("1 - SIM");
        int resposta = scanner.nextInt();
        if (resposta == 1) {
            cargoRepository.deleteById(id);
            System.out.println("Item Deletado");
        } else if (resposta == 0)
            system = false;

    }

    private void visualizar(Scanner scanner) {
        System.out.println("Deseja ver a tabela completa ou quer procurar pelo id de um item? ");
        System.out.println("1 - Tabela completa");
        System.out.println("2 - Procurar por Id");
        int resposta = scanner.nextInt();
        if (resposta == 1) {
            Iterable<Cargo> cargos = cargoRepository.findAll();
            cargos.forEach(c -> System.out.println(c));
        } else if (resposta == 2) {
            System.out.println("Qual o id do item?");
            int id = scanner.nextInt();
            System.out.println(cargoRepository.findById(id));
        }

    }
}

Eu baixei o projeto da aula para comparar com o meu e estavam bem parecidos não consegui encontrar nada que explicava o erro então fui testar o projeto da aula e me deparei com o mesmo problema com o scanner

Fuçando no código encontrei outros problemas alem desse do scanner, como por exemplo, se eu navego muito no menu inicial da aplicação spring como por exemplo acessando um service e saindo dele diversas vezes chega um momento em que mesmo digitando o numero correspondente do service o programa não acessa mais nada e fica voltando no mesmo menu inicial da aplicação.

Qual tabela deseja acessar? 
0 - Sair
1 - Cargo
2 - Funcionario
3 - Unidade
4 - Relatorios
5 - Relatorio Dinamico
2
Qual tabela deseja acessar? 
0 - Sair
1 - Cargo
2 - Funcionario
3 - Unidade
4 - Relatorios
5 - Relatorio Dinamico
2
Qual tabela deseja acessar? 
0 - Sair
1 - Cargo
2 - Funcionario
3 - Unidade
4 - Relatorios
5 - Relatorio Dinamico
2
Qual tabela deseja acessar? 
0 - Sair
1 - Cargo
2 - Funcionario
3 - Unidade
4 - Relatorios
5 - Relatorio Dinamico
2
Qual tabela deseja acessar? 
0 - Sair
1 - Cargo
2 - Funcionario
3 - Unidade
4 - Relatorios
5 - Relatorio Dinamico
2

isso começa a acontecer depois de ficar acessando algum service pelo menu inicial e apertando 0 para voltar a ele por algumas vezes, acontece tanto no meu código como no do professor

Também tive outro problema quando tento salvar um novo funcionário é impossível de adicionar uma unidade a ele

Digite o nome do funcionario
jose
Digite o cpf
9238304
Digite o salario
3000.0
Digite a data de contracao
01/05/2009
Digite o cargoId
1
Digite o unidadeId (Para sair digite 0)
1
Digite o unidadeId (Para sair digite 0)
0

e quando aperto 0 para sair...

java.lang.IllegalStateException: Failed to execute CommandLineRunner ->

Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement ->

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement ->

Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (spring_data_aula.funcionarios_unidades, CONSTRAINT FKgn3jpmj1h0hdy8io3beyrc13i FOREIGN KEY (fk_unidade) REFERENCES unidade_trabalho (id))

Esse problema também aparece tanto no meu código como no do professor. Eu imagino que tenha a ver com a forma que foi configurado o relacionamento entre funcionário porem como o professor não apresentou muito detalhe de como ele definiu os relacionamentos acabei ficando um pouco perdido. (o problema persiste mesmo apagando o banco de dados e começando do zero)

Funcionario

@Entity
@Table(name = "funcionarios")
public class Funcionario {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String nome;
    private String cpf;
    private Double salario;
    private LocalDate dataContratacao;
    @ManyToOne
    @JoinColumn(name = "cargo_id", nullable = false)
    private Cargo cargo;
    @Fetch(FetchMode.SELECT)
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "funcionarios_unidades", joinColumns = {
            @JoinColumn(name = "fk_funcionario") }, 
    inverseJoinColumns = { @JoinColumn(name = "fk_unidade") })
    private List<Unidade> unidades;

Unidade

@Entity
@Table(name = "unidades")
public class Unidade {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String nome;
    private String endereco;
    @ManyToMany(mappedBy = "unidades", fetch = FetchType.EAGER)
    private List<Funcionario> funcionarios;

Eu entendo que são muitas duvidas e que talvez não seja possível responder todas, queria também dizer que nenhum desses problemas me impediu de dar continuidade no curso mas fiquei muito curioso e queria entender o motivo pelo qual eles acontecem (o do scanner principalmente). Aguardo a sua resposta e agradeço desde já.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software