Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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

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!