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

Erro 403 ao agendar consulta

Estou recebendo os seguintes erros no log do programa ao tentar cadastrar a consulta no insomnia:

Hibernate: select u1_0.id, u1_0.login, u1_0.senha from usuarios u1_0 where u1_0.login=? Hibernate: select count() from pacientes p1_0 where p1_0.id=? Hibernate: select count() from medicos m1_0 where m1_0.id=? 2024-07-09T07:21:20.962-03:00 ERROR 8404 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "this.validadores" is null] with root cause

java.lang.NullPointerException: Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "this.validadores" is null at med.voll.api.domain.consulta.AgendaDeConsultas.agendar(AgendaDeConsultas.java:37) ~[classes/:na] at med.voll.api.controller.ConsultaController.agendar(ConsultaController.java:27) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.2.jar:6.0.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.0.2.jar:6.0.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.0.2.jar:6.0.2]...

as classes mencionadas, AgendaDeConsultas:

package med.voll.api.domain.consulta;

import med.voll.api.controller.DadosCancelamentoConsulta; import med.voll.api.domain.ValidacaoException; import med.voll.api.domain.consulta.validacoes.ValidadorAgendamentoDeConsulta; import med.voll.api.domain.medico.Medico; import med.voll.api.domain.medico.MedicoRepository; import med.voll.api.domain.paciente.PacienteRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;

import java.util.List;

@Service public class AgendaDeConsultas {

@Autowired
private ConsultaRepository consultaRepository;

@Autowired
private MedicoRepository medicoRepository;

@Autowired
private PacienteRepository pacienteRepository;

private List<ValidadorAgendamentoDeConsulta> validadores;

public DadosDetalhamentoConsulta agendar(DadosAgendamentoConsulta dados){
    if (!pacienteRepository.existsById(dados.idPaciente())){
        throw new ValidacaoException("Id do paciente informada não existe!");
    }

    if (dados.idMedico() != null && !medicoRepository.existsById(dados.idMedico())){
        throw new ValidacaoException("Id do paciente informada não existe!");
    }

    validadores.forEach(v -> v.validar(dados));

    var paciente = pacienteRepository.getReferenceById(dados.idPaciente());
    var medico = medicoRepository.findById(dados.idMedico()).get();
    var consulta = new Consulta(null, medico, paciente, dados.data());
    consultaRepository.save(consulta);

    return new DadosDetalhamentoConsulta(consulta);
}

private Medico escolherMedico(DadosAgendamentoConsulta dados){
    if (dados.idMedico() != null){
        return medicoRepository.getReferenceById(dados.idMedico());
    }

    if (dados.especialidade() == null){
        throw new ValidacaoException("Especialidade é obrigatória quando o médico não é escolhido!");
    }

    return medicoRepository.escolherMedicoAleatorioLivreNaData(dados.especialidade(), dados.data());
}

public void cancelar(DadosCancelamentoConsulta dados) {
    if (!consultaRepository.existsById(dados.idConsulta())){
        throw new ValidacaoException("Id da consulta não existe!");
    }
    var consulta = consultaRepository.getReferenceById(dados.idConsulta());
    consulta.cancelar(dados.motivo());
}

}

14 respostas

e ConsultaController:

package med.voll.api.controller;

// Trecho de código suprimido

import jakarta.validation.Valid; import med.voll.api.domain.consulta.AgendaDeConsultas; import med.voll.api.domain.consulta.DadosAgendamentoConsulta; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

@RestController @RequestMapping("consultas") public class ConsultaController {

@Autowired
private AgendaDeConsultas agenda;

@PostMapping
@Transactional
public ResponseEntity agendar(@RequestBody @Valid DadosAgendamentoConsulta dados) {
    var dto = agenda.agendar(dados);
    return ResponseEntity.ok(dto);
}

@DeleteMapping
@Transactional
public ResponseEntity cancelar(@RequestBody @Valid DadosCancelamentoConsulta dados) {
    agenda.cancelar(dados);
    return ResponseEntity.noContent().build();
}

}

Oi!

Faltou o @Autowired nesse atributo:

private List<ValidadorAgendamentoDeConsulta> validadores;

Eu estava mexendo em outro banco de dados e acabei excluindo os dados do voll.med sem querer pois esqueci de trocar o nome do codigo que eu copiei, consegui configurar de novo o login pra fazer o cadastro dos pacientes e médicos, mas o cadastro das consultas ainda está gerando erro:

select count(*) from medicos m1_0 where m1_0.id=? Hibernate: select m1_0.ativo from medicos m1_0 where m1_0.id=? Hibernate: select c1_0.id from consultas c1_0 where c1_0.medico_id=? and c1_0.data=? limit ? 2024-07-10T08:08:33.067-03:00 ERROR 15324 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.orm.jpa.JpaSystemException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array] with root cause

org.hibernate.query.QueryTypeMismatchException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array at org.hibernate.query.spi.AbstractSelectionQuery.throwQueryTypeMismatchException(AbstractSelectionQuery.java:348) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]

Manda aqui o código da sua interface MedicoRepository

aqui:

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

@Query("""
        select m.ativo
        from Medico m
        where
        m.id = :id
        """)

Boolean findAtivoById(Long id);

}

Manda aqui o código dos outros repositories também: PacienteRepository e ConsultaRepository.

E mande a stacktrace completa

Agora apareceu esse, mas eu nem mexi nada no código:

Hibernate: select u1_0.id, u1_0.login, u1_0.senha from usuarios u1_0 where u1_0.login=? Hibernate: select count() from pacientes p1_0 where p1_0.id=? Hibernate: select count() from medicos m1_0 where m1_0.id=? Hibernate: select m1_0.ativo from medicos m1_0 where m1_0.id=? Hibernate: select c1_0.id from consultas c1_0 where c1_0.medico_id=? and c1_0.data=? limit ? 2024-07-10T20:33:47.362-03:00 ERROR 4052 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.orm.jpa.JpaSystemException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array] with root cause

org.hibernate.query.QueryTypeMismatchException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array at org.hibernate.query.spi.AbstractSelectionQuery.throwQueryTypeMismatchException(AbstractSelectionQuery.java:348) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.verifyResultType(AbstractSelectionQuery.java:338) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.checkQueryReturnType(AbstractSelectionQuery.java:286) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.visitQueryReturnType(AbstractSelectionQuery.java:228) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.sqm.internal.QuerySqmImpl.(QuerySqmImpl.java:263) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:1303) ~[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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]...

todos eles dão erro 403 no Insomnia ao tentar cadastrar a consulta

Toda vez que eu abro e fecho o InteliJ o número do erro muda:

Hibernate: select u1_0.id, u1_0.login, u1_0.senha from usuarios u1_0 where u1_0.login=? Hibernate: select count() from pacientes p1_0 where p1_0.id=? Hibernate: select count() from medicos m1_0 where m1_0.id=? Hibernate: select m1_0.ativo from medicos m1_0 where m1_0.id=? Hibernate: select c1_0.id from consultas c1_0 where c1_0.medico_id=? and c1_0.data=? limit ? 2024-07-10T20:39:32.178-03:00 ERROR 6084 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.orm.jpa.JpaSystemException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array] with root cause

org.hibernate.query.QueryTypeMismatchException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array at org.hibernate.query.spi.AbstractSelectionQuery.throwQueryTypeMismatchException(AbstractSelectionQuery.java:348) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.verifyResultType(AbstractSelectionQuery.java:338) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.checkQueryReturnType(AbstractSelectionQuery.java:286) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.visitQueryReturnType(AbstractSelectionQuery.java:228) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.sqm.internal.QuerySqmImpl.(QuerySqmImpl.java:263) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:1303) ~[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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[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 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:307) ~[spring-orm-6.0.2.jar:6.0.2] at jdk.proxy4/jdk.proxy4.$Proxy121.createQuery(Unknown Source) ~[na:na]...

ConsultaRepository

package med.voll.api.domain.consulta;

import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDateTime;

public interface ConsultaRepository extends JpaRepository<Consulta, Long> {

boolean existsByPacienteIdAndDataBetween(Long idPaciente, LocalDateTime primeiroHorario, LocalDateTime ultimoHorario);

boolean existsByMedicoIdAndData(Long idMedico, LocalDateTime data);

}

PacienteRepository:

package med.voll.api.domain.paciente;

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

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

Boolean findAtivoById(Long id);

}

Hibernate: select u1_0.id, u1_0.login, u1_0.senha from usuarios u1_0 where u1_0.login=? Hibernate: select count() from pacientes p1_0 where p1_0.id=? Hibernate: select count() from medicos m1_0 where m1_0.id=? Hibernate: select m1_0.ativo from medicos m1_0 where m1_0.id=? Hibernate: select c1_0.id from consultas c1_0 where c1_0.medico_id=? and c1_0.data=? limit ? 2024-07-10T20:47:52.461-03:00 ERROR 5676 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.orm.jpa.JpaSystemException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array] with root cause

org.hibernate.query.QueryTypeMismatchException: Specified result type [java.lang.Boolean] did not match Query selection type [med.voll.api.domain.paciente.Paciente] - multiple selections: use Tuple or array at org.hibernate.query.spi.AbstractSelectionQuery.throwQueryTypeMismatchException(AbstractSelectionQuery.java:348) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.verifyResultType(AbstractSelectionQuery.java:338) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.checkQueryReturnType(AbstractSelectionQuery.java:286) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.spi.AbstractSelectionQuery.visitQueryReturnType(AbstractSelectionQuery.java:228) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.query.sqm.internal.QuerySqmImpl.(QuerySqmImpl.java:263) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:1303) ~[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.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[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 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

solução!

O problema está na sua itnerface PacienteRepository, no método findAtivoById. Faltou adicioanr a query no método:

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

Agora está dando erro na data, mas eu estou passando o data certa no Insomnia, inclusive quando eu coloco uma data que ja passou, ele me informa que não pode ser uma data passada.

Hibernate: insert into consultas (data, medico_id, motivo_cancelamento, paciente_id) values (?, ?, ?, ?) 2024-07-11T10:42:05.561-03:00 WARN 19340 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000 2024-07-11T10:42:05.562-03:00 ERROR 19340 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'data' cannot be null 2024-07-11T10:42:05.564-03:00 ERROR 19340 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]] with root cause

java.sql.SQLIntegrityConstraintViolationException: Column 'data' cannot be null at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-5.0.1.jar:na] at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-5.0.1.jar:na] at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3288) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3898) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:80) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:653) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]

Manda o código da sua classe Consulta

package med.voll.api.domain.consulta;

import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import med.voll.api.controller.MotivoCancelamento; import med.voll.api.domain.medico.Medico; import med.voll.api.domain.paciente.Paciente;

import java.time.LocalDateTime;

@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;

public Consulta(Object o, Medico medico, Paciente paciente, LocalDateTime data) {
}


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

public Long getId() {
    return id;
}

public Medico getMedico() {
    return medico;
}

public Paciente getPaciente() {
    return paciente;
}

public LocalDateTime getData() {
    return data;
}

public MotivoCancelamento getMotivoCancelamento() {
    return motivoCancelamento;
}

}

Ta faltando o @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "data")

ali no private LocalDateTime data; né