16
respostas

java.sql.SQLIntegrityConstraintViolationException: Column 'crm' cannot be null

Olá a todos, Na aula da nava migration está ocorrendo essa exception abaixo. Alguem sabe oque poderia ser?

java.sql.SQLIntegrityConstraintViolationException: Column 'crm' cannot be null
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) ~[mysql-connector-j-8.0.33.jar:8.0.33]
    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.7.Final.jar:6.1.7.Final]
    at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3342) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3980) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:80) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:653) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:283) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:264) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:322) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:340) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:184) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:129) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:53) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:737) ~[hibernate-core-6.1.7.Final.jar:6.1.7.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:721) ~[hibernate-core-6.1.7.Final.jar:6.1.7.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 
16 respostas

Pelo que entendi, o campo crm foi adicionado como not null mas ja há registro de medico no banco de dados. Neste caso, para rodar a nova migration, vejo quatro opções:

  1. executar no banco de dados o comando update do crm dos medicos o banco de dados, update medicos set crm ='' where crm is null
  2. executar no banco de dado comando para deletar todos os registros de medicos no banco de dados, delete from [nome da tabela];
  3. alterar o script da nova migration para que o campo crm possa ser null;
  4. apagar e criar novamente o banco de dados, é comentado no proximo topico.

Edição: tinha entendido que o problema seria ao rodar a migration.

Estou com o mesmo problema do colega, e infelizmente nenhumas destas soluções deram certo pra min.

O problema ocorre quando vai rodar a nova migration, ou ao cadastrar ou atualizar o médico, ou em outra situação?

Quando eu tento mandar a requisição com o imsominia.

Acredito que o problema seria na propriedade crm do médico, na requisição para API ao cadastrar ou atualizar, ou não está sendo informado ou está sendo informado com o valor null. Tu tens o código do MedicoController e da classe DadosCadastroMedico? Qual requisição está sendo feita?

package med.voll.api.controller;

import jakarta.transaction.Transactional; import jakarta.validation.Valid; import med.voll.api.endereco.Endereco; import med.voll.api.medico.DadosCadastroMedico; import med.voll.api.medico.Medico; import med.voll.api.medico.MedicoRepository; import org.springframework.beans.factory.annotation.Autowired; 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("medicos") public class MedicoController {

@Autowired
private MedicoRepository repository;

@PostMapping
@Transactional
public void cadastrar(@RequestBody @Valid DadosCadastroMedico dados){
    repository.save(new Medico(dados));

}

}

public record DadosCadastroMedico( @NotBlank String nome, @NotBlank @Email String email,

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

    @NotNull
    Especialidade especialidade,

    @NotNull
    @Valid
    DadosEndereco endereco) {

}

Estava funcionando corretamente, só que depois que foi criado a tabela e feito as adições no código ai começa a dar o erro.

Como está o código da classe Medico?

Pelo menos com o que foi apresentado, até o momento, não encontrei inconsistência em DadosCadastroMedico e MedicoController .

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

@Enumerated(EnumType.STRING)
private Especialidade especialidade;

@Embedded
private Endereco endereco;

public Medico(DadosCadastroMedico dados) {

    this.nome = nome;
    this.email = email;
    this.crm = crm;
    this.especialidade = dados.especialidade();
    this.endereco = new Endereco(dados.endereco());

}

}

entendi! Ai está a classe Medico

No construtor de Medico(DadosCadastroMedico dados) faria assim:

public Medico(DadosCadastroMedico dados) {

    this.nome = dados.nome();
    this.email = dados.email();
    this.crm = dados.crm();
    this.especialidade = dados.especialidade();
    this.endereco = new Endereco(dados.endereco());

}

Com this.crm = crm; estava chamando o crm da instância (que ao criar está null), e não o crm() do parâmetro dados.

Opa muito obrigado!! Acabou dando um erro envolvendo o endereço também, então mudei o construtor e deu certo:

public Endereco(DadosEndereco endereco) { this.logradouro = endereco.logradouro(); this.bairro = endereco.bairro(); this.cep = endereco.cep(); this.numero = endereco.numero(); this.complemento = endereco.complemento(); this.cidade = endereco.cidade(); this.uf = endereco.uf(); }

Show de bola :D.