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

[Dúvida] Erro ao compilar depois de implementar os códigos de cancelamento

Boa Tarde Professor!

Implementei os códigos conforme o está nas suas respostas, mas o erro persiste, tentei analisar e refazer mas não consegui identififcar. Acredito que seja um erro na query mas como não entendo muito de jpql não consegui identificar.

**Erro: **

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2023-11-29T14:34:34.246-03:00 ERROR 13136 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'consultaController': Unsatisfied dependency expressed through field 'agenda': Error creating bean with name 'agendaDeConsultas': Unsatisfied dependency expressed through field 'medicoRepository': Error creating bean with name 'medicoRepository' defined in med.voll.api.domain.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:127) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1397) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.2.jar:6.0.2] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.2.jar:6.0.2] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.0.jar:3.0.0] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.0.jar:3.0.0] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.0.jar:3.0.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.0.jar:3.0.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.0.jar:3.0.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.0.jar:3.0.0] at med.voll.api.ApiApplication.main(ApiApplication.java:10) ~[classes/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-3.0.0.jar:3.0.0]

8 respostas

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'agendaDeConsultas': Unsatisfied dependency expressed through field 'medicoRepository': Error creating bean with name 'medicoRepository' defined in med.voll.api.domain.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:127) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1397) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ~[spring-beans-6.0.2.jar:6.0.2] ... 23 common frames omitted

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'medicoRepository' defined in med.voll.api.domain.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract med.voll.api.domain.medico.Medico med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) ~[spring-beans-6.0.2.jar:6.0.2] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709) ~[spring-beans-6.0.2.jar:6.0.2] ... 37 common frames omitted

Caused by: java.lang.IllegalArgumentException: org.hibernate.query.sqm.InterpretationException: Error interpreting 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

]; this may indicate a semantic (user query) problem or a bug in the parser [ 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

] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:141) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:175) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:182) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:761) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:663) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:127) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:360) ~[spring-orm-6.0.2.jar:6.0.2] at jdk.proxy4/jdk.proxy4.$Proxy121.createQuery(Unknown Source) ~[na:na] at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:94) ~[spring-data-jpa-3.0.0.jar:3.0.0] ... 65 common frames omitted Caused by: org.hibernate.query.sqm.InterpretationException: Error interpreting 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

]; this may indicate a semantic (user query) problem or a bug in the parser [ 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

] at org.hibernate.query.hql.internal.StandardHqlTranslator.translate(StandardHqlTranslator.java:97) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.lambda$createQuery$2(AbstractSharedSessionContract.java:748) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.createHqlInterpretation(QueryInterpretationCacheStandardImpl.java:141) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.resolveHqlInterpretation(QueryInterpretationCacheStandardImpl.java:128) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:745) ~[hibernate-core-

Class transformation time: 0.0976943s for 11117 classes or 8.787829450391293E-6s per class

Process finished with exit code 0

Oi!

Está com erro no método escolherMedicoAleatorioLivreNaData.

Manda o código das classes: Medico, Consulta e MedicoRepository

Classe Consulta

package med.voll.api.domain.consulta;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import med.voll.api.domain.medico.Medico;
import med.voll.api.domain.paciente.Paciente;

import java.time.LocalDateTime;

@Entity(name = "Consulta")
@Table(name = "consultas")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Consulta {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "medico_id")
    private Medico idMedico;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "paciente_id")
    private Paciente idPaciente;

    private LocalDateTime data;

    @Column(name = "motivo_cancelamento")
    @Enumerated(EnumType.STRING)
    private MotivoCancelamento motivoCancelamento;

    public void cancelar(MotivoCancelamento motivo) {
        this.motivoCancelamento = motivo;
    }

}

Classe Medico

package med.voll.api.domain.medico;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import med.voll.api.domain.endereco.Endereco;

@Table(name = "medicos")
@Entity(name = "Medico")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Medico {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String nome;
    private String email;

    private String telefone;

    private String crm;

    @Enumerated(EnumType.STRING)
    private Especialidade especialidade;

    @Embedded
    private Endereco endereco;

    private Boolean ativo;

    public Medico(DadosCadastroMedico dados) {
        this.ativo = true;
        this.nome = dados.nome();
        this.email = dados.email();
        this.telefone = dados.telefone();
        this.crm = dados.crm();
        this.especialidade = dados.especialidade();
        this.endereco = new Endereco(dados.endereco());
    }

    public void atualizarInformacoes(DadosAtualizacaoMedico dados) {
        if (dados.nome() != null) {
            this.nome = dados.nome();
        }
        if (dados.telefone() != null) {
            this.telefone = dados.telefone();
        }
        if (dados.endereco() != null) {
            this.endereco.atualizarInformacoes(dados.endereco());
        }

    }

    public void excluir() {
        this.ativo = false;
    }
}

Classe MedicoRepository

package med.voll.api.domain.medico;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.time.LocalDateTime;

public interface MedicoRepository extends JpaRepository<Medico, Long> {
    Page<Medico> findAllByAtivoTrue(Pageable paginacao);

    //como o nome do método não está no padrão em inglês do spring precisamos montar a querie de pesquisa
    // a anotação indica o uso da querie.

    @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 escolherMedicoAleatorioLivreNaData(Especialidade especialidade, LocalDateTime data);

}
solução!

Na sua classe Consulta você chamou o atributo de idMedico:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "medico_id")
private Medico idMedico;

Então na query deve usar ess mesmo nome:

m.id not in(
    select c.idMedico.id from Consulta c
    where
    c.data = :data
)

Deu certo professor! Muito obrigada! Deus te abençoe! :) :) Aproveitando pra te dar um feedback: estou gostando muito do curso, sua didática é excelente e fica fácil demais aprender java com o jeito que explica. Obrigada :)

Show!

Valeu pelo feedback :)

Bons estudos!