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

[Dúvida] @AllArgsConstructor parece não funcionar

No meu projeto, na classe Consulta tenho que manter o construtor public Consulta(Object o, Medico medico, Paciente paciente, LocalDateTime data) { }

pois se não o programa me retorna o seguinte erro: java: no suitable constructor found for Consulta(,med.voll.api.domain.medico.Medico,med.voll.api.domain.paciente.Paciente,java.time.LocalDateTime) constructor med.voll.api.domain.consulta.Consulta.Consulta() is not applicable (actual and formal argument lists differ in length) constructor med.voll.api.domain.consulta.Consulta.Consulta(java.lang.Long,med.voll.api.domain.medico.Medico,med.voll.api.domain.paciente.Paciente,java.time.LocalDateTime,med.voll.api.controller.MotivoCancelamento) is not applicable (actual and formal argument lists differ in length)

ele acusa erro na classe AgendaDeConsultas, na parte var consulta = new Consulta(null, medico, paciente, dados.data());:

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

}

o @AllArgsConstructor não serve pra emular esses tipos de construtores?

16 respostas

Oi!

Manda aqui a sua classe Consulta.

Aqui está:

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

}

Sua classe Consulta já está com o atributo motivoCancelamento, então precisa passar null pra ele também:

var consulta = new Consulta(null, medico, paciente, dados.data(), null);

Na propria classe consulta?

Essa linha que mandei na mensagem anterior é no método agendar, da classe AgendaDeConsultas, antes de chamar o save do repository.

No seu código já tem essa linha, mas está sem o último parâmetro null

Ah, entendi, mas tenho que mexer em algo mais? a classe está indicando erro: 'Consulta(java.lang.Object, med.voll.api.domain.medico.Medico, med.voll.api.domain.paciente.Paciente, java.time.LocalDateTime)' in 'med.voll.api.domain.consulta.Consulta' cannot be applied to '(null, med.voll.api.domain.medico.Medico, med.voll.api.domain.paciente.Paciente, java.time.@jakarta.validation.constraints.NotNull @jakarta.validation.constraints.Future LocalDateTime, null)'

Pode apagar esse construtor que você criou na classe Consulta:

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

O erro persiste ainda

'Consulta()' cannot be applied to '(null, med.voll.api.domain.medico.Medico, med.voll.api.domain.paciente.Paciente, java.time.@jakarta.validation.constraints.NotNull @jakarta.validation.constraints.Future LocalDateTime, null)'

Estou achando que o Lombok não está instalado no seu IntelliJ.

Abra o menu de configurações (atalho: CTRL + ALT + S) e entre na opção plugins, para verificar se o Lombok está instalado:

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

Se ele não aparece na aba installed, vai na aba Marketplace para pesquisar e instalar.

Está instalado e com essa dependência

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

org.projectlombok lombok true org.springframework.boot spring-boot-maven-plugin --> --> org.projectlombok--> lombok--> --> -->

tentei rodar sem o ali mas não muda nada

Hibernate: insert into consultas (data, medico_id, motivo_cancelamento, paciente_id) values (?, ?, ?, ?) 2024-07-11T13:31:50.427-03:00 WARN 3156 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000 2024-07-11T13:31:50.427-03:00 ERROR 3156 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'data' cannot be null 2024-07-11T13:31:50.441-03:00 ERROR 3156 --- [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.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]] with root cause

Compartilha teu projeto aqui. Pode ser pelo GitHub

https://github.com/Eric-Nascimento/MedApi

solução!

Na classe AgendaDeConsultas o método deve ficar assim:

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(), null);
    consultaRepository.save(consulta);

    return new DadosDetalhamentoConsulta(consulta);
}

E a classe Consulta deve ficar assim:

@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 void cancelar(MotivoCancelamento motivo){
        this.motivoCancelamento = motivo;
    }

}

Não consegui achar diferença entre o que você mandou e o que está no meu código, só a parte do AgendaDeConsultas que está var consulta = new Consulta(null, medico, paciente, dados.data());, pois se eu colocar o , null como ultimo parametro, ele da erro como mencionei la em cima, ai eu não consigo rodar o programa

Copiando os códigos que te mandei funciona normalmente. A mudança principal foi na classe Consulta, que apaguei o construtor e os métodos getters, pois a classe já está anotada com @Getter do Lombok.

Ah, tinha que apagar os Getters também, eu tinha deixado por que a outra classe estava pedindo, ele não estava conseguindo chamar pelo do Lombok, devia ter algo bugado, agora está funcionando até o cadastro consulta que estava dando erro anteriormente, obrigado!