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);
}