6
respostas

[Bug] Erro tabela

Rodando o projeto ele cria a tabela no banco de dados, porem o campo crm esta dando este erro

org.hibernate.exception.DataException: could not execute statement [Data truncation: Data too long for column 'crm' at row 1] [insert into medicos (ativo,crm,email,bairro,cep,cidade,complemento,logradouro,numero,uf,especialidade,nome,telefone) values (?,?,?,?,?,?,?,?,?,?,?,?,?)]
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:55)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:58)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
    at org.hibernate.id.insert.GetGeneratedKeysDelegate.performInsert(GetGeneratedKeysDelegate.java:107)
    at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorPostInsertSingleTable.execute(MutationExecutorPostInsertSingleTable.java:100)
    at org.hibernate.persister.entity.mutation.InsertCoordinator.doStaticInserts(InsertCoordinator.java:175)
    at org.hibernate.persister.entity.mutation.InsertCoordinator.coordinateInsert(InsertCoordinator.java:113)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2868)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:670)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:291)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:272)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:322)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:386)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:300)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:219)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:134)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:175)
    at org.hibernate.event.internal.DefaultPersistEventListener.persist(DefaultPersistEventListener.java:93)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:77)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:54)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:754)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:738)
    at org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager.persist(TestEntityManager.java:92)
    at med.absolut.api.medico.test.MedicoRepositoryTest.cadastrarMedico(MedicoRepositoryTest.java:73)
    at med.absolut.api.medico.test.MedicoRepositoryTest.escolherMedicoAleatoriamenteCenario1(MedicoRepositoryTest.java:47)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'crm' at row 1
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:912)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1054)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1003)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1312)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:988)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
6 respostas

e assim esta minha classe do test:

package med.absolut.api.medico.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.ActiveProfiles;

import jakarta.persistence.Table;
import med.absolut.api.consulta.Consulta;
import med.absolut.api.endereco.DadosEndereco;
import med.absolut.api.medico.DadosMedico;
import med.absolut.api.medico.Especialidades;
import med.absolut.api.medico.Medico;
import med.absolut.api.medico.MedicoRepository;
import med.absolut.api.paciente.DadosPaciente;
import med.absolut.api.paciente.Paciente;

@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
@Table(name = "medicos")
@ActiveProfiles("test")
class MedicoRepositoryTest {

    @Autowired
    private MedicoRepository medicoRepository;

    @Autowired
    private TestEntityManager em;

    @Test
    @DisplayName("Deveria devolver null quando unico medico cadastrado nao esta disponivel na data")
    void escolherMedicoAleatoriamenteCenario1() {

        var proximaSegundaAs10 = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).atTime(10, 0);

        var medico = cadastrarMedico("Medico", "medico@email.com", "123456", Especialidades.CARDIOLOGIA);
        var paciente = cadastrarPaciente("Paciente", "paciente@email.com", "00000000000");
        cadastrarConsulta(medico, paciente, proximaSegundaAs10);

        var medicoLivre = medicoRepository.escolherMedicoAleatoriamente(Especialidades.CARDIOLOGIA, proximaSegundaAs10);
        assertThat(medicoLivre).isNull();
    }

    private void cadastrarConsulta(Medico medico, Paciente paciente, LocalDateTime data) {
        em.persist(new Consulta(
                null, 
                medico, 
                paciente, 
                data
            )
        );
    }

    private Medico cadastrarMedico(String nome, String email, String crm, Especialidades especialidade) {
        var medico = new Medico(dadosMedico(
                nome, 
                email, 
                crm, 
                especialidade
            )
        );	
        em.persist(medico);
        return medico;
    }

    private Paciente cadastrarPaciente(String nome, String email, String cpf) {
        var paciente = new Paciente(dadosPaciente(
                nome, 
                email, 
                cpf
             )
        );
        em.persist(paciente);
        return paciente;
    }

    private DadosMedico dadosMedico(String nome, String email, String crm, Especialidades especialidade) {
        return new DadosMedico(
                null, 
                nome, 
                email, 
                "61999999999", 
                crm, 
                especialidade, 
                dadosEndereco()
        );
    }

    private DadosPaciente dadosPaciente(String nome, String email, String cpf) {
        return new DadosPaciente(
                null, 
                nome, 
                email, 
                "61999999999", 
                cpf, 
                dadosEndereco()
        );
    }

    private DadosEndereco dadosEndereco() {
        return new DadosEndereco(
                "rua xpto", 
                "bairro", 
                "00000000", 
                "Brasilia", 
                "DF", 
                null, 
                null
        );
    }
}

Oi!

Manda aqui suas classes Medico, DadosMedico e a migration de criação da tabela de médicos

package med.absolut.api.medico;

import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import med.absolut.api.endereco.Endereco;

@Table(name = "medicos")
@Entity(name = "Medico")
@Getter
@NoArgsConstructor
@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;

    @Enumerated(EnumType.STRING) 
    private Especialidades especialidade;

    @Embedded
    private Endereco endereco;

    private Boolean ativo;

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

    public void atualizaInformacao(DadosAtualizadoMedico dados) {
        if(dados.id() != null) {
            this.id = dados.id();
        }

        if(dados.nome() != null) {
            this.nome = dados.nome();
        }

        if(dados.telefone()!= null) {
            this.telefone = dados.telefone();
        }
    }

    public void excluir() {
        this.ativo = false;
    }
}
package med.absolut.api.medico;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import med.absolut.api.endereco.DadosEndereco;

public record DadosMedico(

        Long id,

        @NotBlank
        String nome,

        @NotBlank
        @Email
        String email,

        @NotBlank
        @Pattern(regexp = "\\d{6}")
        String crm,

        @NotBlank
        @Pattern(regexp = "\\d{11}")
        String telefone,

        @NotNull
        Especialidades especialidade,

        @NotNull @Valid
        DadosEndereco endereco
        ) {
}
CREATE TABLE `medicos` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `nome` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `crm` varchar(6) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL,
  `telefone` varchar(11) NOT NULL,
  `especialidade` varchar(45) NOT NULL,
  `logradouro` varchar(100) NOT NULL,
  `bairro` varchar(45) NOT NULL,
  `cep` varchar(9) NOT NULL,
  `cidade` varchar(100) NOT NULL,
  `complemento` varchar(45) DEFAULT NULL,
  `numero` varchar(45) DEFAULT NULL,
  `uf` varchar(2) NOT NULL,
  `ativo` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

O problema está nesse método da sua classe de teste:

private DadosMedico dadosMedico(String nome, String email, String crm, Especialidades especialidade) {
    return new DadosMedico(
            null, 
            nome, 
            email, 
            "61999999999", 
            crm, 
            especialidade, 
            dadosEndereco()
    );
}

Você inverteu os parâmetros crm e telefone. O crm deve ser passado antes do telefone.

Funcionou professor, só uma ultima duvida, eu tenho que crias as tabelas de consulta e paciente tambem?

Sim, uma nova migration para cada nova tabela que precisar no banco de dados.