Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Bug] Erro ao inicializar

Meu projeto não está iniciando.

Trace: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'consultaController' defined in file [C:\Users\Samsung\IdeaProjects\gerenciamento-de-clinicas\target\classes\med\voll\api\controller\ConsultaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'consultaService': Unsatisfied dependency expressed through field 'medicoRepository': Error creating bean with name 'medicoRepository' defined in med.voll.api.repository.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long); Reason: Validation failed for query for method public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long)

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'consultaService': Unsatisfied dependency expressed through field 'medicoRepository': Error creating bean with name 'medicoRepository' defined in med.voll.api.repository.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long); Reason: Validation failed for query for method public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'medicoRepository' defined in med.voll.api.repository.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long); Reason: Validation failed for query for method public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long)

Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long); Reason: Validation failed for query for method public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long)

Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.lang.Boolean med.voll.api.repository.MedicoRepository.findAtivoById(java.lang.Long)

Caused by: java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'Medico'

Caused by: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'Medico'

Projeto: https://github.com/Gustavo-AOliveira/gerenciamento-de-clinicas

2 respostas
solução!

Oi Gustavo, rodei seu projeto aqui...

Tem alguns detalhe pra corrigir. O primeiro que encontrei foi a sua anotação @Entity, nela você preencheu com "name = "Médico", o correto "name = Medico".

Os outros problemas estão no MedicoRepository:


// Aqui
public interface MedicoRepository extends JpaRepository<Medico, Long> {
    Page<Medico> findAllByAtivoTrue(Pageable paginacao);
    @Query("""
            select m from medico m
            where
            m.ativo = true
            and
            m.especialidade = :especialidade
            and
            m.id not in(
                select c.medico.id from Consulta c
                where
                c.data = :data
            )
            order by rand()
            limit 1
            """)
    Medico randomMedicoDisponivel(Especialidade especialidade, LocalDateTime data);

    @Query("""
            select m.ativo
            from Medico m
            where
            m.id = :id
            """)
    Boolean findAtivoById(Long id);

    // Aqui
    Boolean existsByMedicoIdAndData(Long idMedico, LocalDateTime data);
}

Correções:

1 - No método findAllByAtivoTrue você passou "from medico" na query, mas em JPQL, quando vamos apontar uma entidade, precisamos passar o nome da classe. O correto seria "from Medico"

2 - O seu método existsByIdAndData(Long idMedico, LocalDateTime data) também tem um problema. A entidade Medico não tem um atributo medico_id e também não tem um atributo data. Tem uma classe de validação que usa esse método:

@Component
public class ValidadorMedicoConsultaMesmoHorario implements ValidadorAgendamentoConsulta{
    @Autowired
    private MedicoRepository repository;

    public void validar(DadosAgendamentoConsulta data){
        var medicoPossuiOutraConsultaMesmoHorario = repository.existsByMedicoIdAndData(data.idMedico(), data.data());
        if(medicoPossuiOutraConsultaMesmoHorario){
            throw new ConsultaException("Médico já possui outra consulta agendada nesse horário");
        }
    }
}

Esses atributos medico_id e data na verdade são do objeto Consulta, colocando esse método dentro de MedicoRepository você está fazendo o Spring buscar a informação no lugar errado, na tabela medicos, mas esses dados estão na tabela consultas. Então, o correto é fazer esse chamado usando o ConsultaRepository:

  • Remova o método existsByMedicoIdAndData() de MedicoRepository e passe-o para ConsultaRepository
  • Substitua o MedicoRepository por ConsultaRepository na classe ValidadorMedicoConsultaMesmoHorario

Assim:

@Component
public class ValidadorMedicoConsultaMesmoHorario implements ValidadorAgendamentoConsulta{
    @Autowired
    private ConsultaRepository consultaRepository;

    public void validar(DadosAgendamentoConsulta data){
        var medicoPossuiOutraConsultaMesmoHorario = consultaRepository.existsByMedicoIdAndData(data.idMedico(), data.data());
        if(medicoPossuiOutraConsultaMesmoHorario){
            throw new ConsultaException("Médico já possui outra consulta agendada nesse horário");
        }
    }
}

Acredito que isso deve resolver, caso não dê certo avise aqui novamente. Espero que tenha ajudado, bons estudos!

Ele está inicializando normal agora porém quando faço a requisição de agendar ele retorna: jakarta.persistence.NonUniqueResultException: query did not return a unique result: 3

{
"idPaciente": 3,
"idMedico": 3,
"data": "08/03/2024 13:45"

}