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

[Dúvida] Error interpreting query na query de medicoRepository

Após colocar a query em code block ("""), comecei a receber tal erro:

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 com.br.med.voll.api.domain.medico.MedicoRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract com.br.med.voll.api.domain.medico.Medico com.br.med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(com.br.med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime); Reason: Validation failed for query for method public abstract com.br.med.voll.api.domain.medico.Medico com.br.med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(com.br.med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime)
    ...
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.br.med.voll.api.domain.medico.Medico com.br.med.voll.api.domain.medico.MedicoRepository.escolherMedicoAleatorioLivreNaData(com.br.med.voll.api.domain.medico.Especialidade,java.time.LocalDateTime)
    ...
Caused by: java.lang.IllegalArgumentException: org.hibernate.query.sqm.InterpretationException: Error interpreting query [select m from Medico m
where
m.ativo = 1
and
m.especialidade = :especialidade
and
m.id not in (
    select c.medico.id from Consulta c
    where
    c.data = :data
    and
    c.motivo_cancelamento is null
)
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 = 1
and
m.especialidade = :especialidade
and
m.id not in (
    select c.medico.id from Consulta c
    where
    c.data = :data
    and
    c.motivo_cancelamento is null
)
order by rand()
limit 1
]
(Não entendi o motivo da query aparecer duas vezes no console).

Seguem as classes:

(Omitindo imports desnecessários)

@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;
    private Boolean ativo;

    @Enumerated(EnumType.STRING)
    private Especialidade especialidade;

    @Embedded
    private Endereco endereco;

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

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


(Omitindo imports desnecessários)

@Table(name = "consultas")
@Entity(name = "Consulta")
@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 medico;

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

    private LocalDateTime data;

    @Column(name = "motivo_cancelamento")
    @Enumerated(EnumType.STRING)
    private MotivoCancelamento motivoCancelamento;
}
(Omitindo imports desnecessários)

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

    @Query("""
        select m from Medico m
        where
        m.ativo = 1
        and
        m.especialidade = :especialidade
        and
        m.id not in (
            select c.medico.id from Consulta c
            where
            c.data = :data
            and
            c.motivo_cancelamento is null
        )
        order by rand()
        limit 1
        """)
    Medico escolherMedicoAleatorioLivreNaData(Especialidade especialidade, LocalDateTime data);

    @Query("""
            select m.ativo
            from Medico m
            where m.id = :id
            """)
    Boolean findAtivoById(Long id);
}
2 respostas
solução!

Oi Yago!

Acho que o problema está aqui: c.motivo_cancelamento is null

Deveria ser motivoCancelamento (nome do atributo) e não motivo_cancelamento (nome da coluna na tabela)

Deu certo, obrigado!