Camp Enum nulo na consulta - resolvido

Fiz esta consulta. Mas se o campo PessoaTipoEnum pessoaTipo, é nulo dá erro na criação da consulta

Page<Pessoa> findByPessoaTipoAndNomeRazaoLikeAndFantasiaSobreNomeLikeAndIdentidadeAndDocumentoAndInscricaoMunicipalAndInscricaoEstadual(PessoaTipoEnum pessoaTipo, String nomeRazao, String fantasiaSobreNome, String identidade, String documento, String inscricaoMunicipal, String inscricaoEstadual, Pageable pageable);

java.lang.IllegalArgumentException: Value must not be null!
	at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterMetadataProvider$ParameterMetadata.prepare(ParameterMetadataProvider.java:236) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory$CriteriaQueryParameterSetterFactory.getAndPrepare(QueryParameterSetterFactory.java:318) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory$CriteriaQueryParameterSetterFactory.lambda$create$1(QueryParameterSetterFactory.java:309) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.QueryParameterSetter$NamedOrIndexedQueryParameterSetter.setParameter(QueryParameterSetter.java:82) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinder.lambda$bind$0(ParameterBinder.java:79) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_221]
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1082) ~[na:1.8.0_221]
	at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:79) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:74) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:96) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:246) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:173) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:94) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:210) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:199) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:144) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$ExposeRepositoryInvocationInterceptor.invoke(CrudMethodMetadataPostProcessor.java:364) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at br.com.ghsistemas.usuarios.core.pessoa.impl.$Proxy139.findByPessoaTipoAndNomeRazaoLikeAndFantasiaSobreNomeLikeAndIdentidadeAndDocumentoAndInscricaoMunicipalAndInscricaoEstadual(Unknown Source) ~[na:na]

O campo está mapeado assim:

@Column(name = "ST_TIPO_PESSOA", length = 10, nullable = false)
@Enumerated(STRING)
private PessoaTipoEnum pessoaTipo;

É isto mesmo ?

Nao entendo muito de JPA, mas isso aqui diz que nao aceita null: nullable = false, muda pra true.

Não é isso

Page<DicionarioSenha> findByPalavraLike(String palavra, Pageable pageable);

Esta já funciona:

@Column(name = "DS_PALAVRA", nullable = false, length = 300)
    private String palavra;

Isto é só para criação de tabela, quando o se faz pelo JPA.

Vc podia fazer um teste?

Basicamente é o seguinte;

@Column(name = "ST_TIPO_PESSOA", length = 10, nullable = false)
private String pessoaTipo;

private void setPessoa(PessoaTipoEnum tipo){
  this.pessoaTipo = tipo+"";
}
//método opcional
private String getPessoaTipo(){
  return pessoaTipo;
}

private PessoaTipoEnum  getPessoaTipoEnum(){
   return PessoaTipoEnum.find(pessoaTipo);// criar o método que retorna a enum pelo nome
}

Eu também não tenho muito traquejo com o hibernate.

Mas este wrapper não afeta a lógica e permite saber se o problema é na enum.

Veja se isso ajuda: https://docs.spring.io/spring-data/jpa/docs/2.0.3.RELEASE/reference/html/#repositories.nullability

Esse link diz que vc consegue usar a anotação @Nullable no parâmetro para ele ser desconsiderado na consulta nesse caso.

Page<Pessoa> findByPessoaTipoAndNomeRazaoLikeAndFantasiaSobreNomeLikeAndIdentidadeAndDocumentoAndInscricaoMunicipalAndInscricaoEstadual(
    @Nullable PessoaTipoEnum pessoaTipo,
    String nomeRazao,
    String fantasiaSobreNome, 
    String identidade, 
    String documento, 
    String inscricaoMunicipal, 
    String inscricaoEstadual, 
    Pageable pageable);

Não funcionou. Mesmo erro

Meu getter e setter são criados pelo lombok.

Em cada enum que crio, crioum metodo para buscar.

No serviço chamo assim:

Page<Pessoa> pessoas = repository.findByPessoaTipoAndNomeRazaoLikeAndFantasiaSobreNomeLikeAndIdentidadeAndDocumentoAndInscricaoMunicipalAndInscricaoEstadual(
                buscaTipoEnum(filtro.getPessoaTipo()),
                isEmpty(filtro.getNomeRazao()) ? null : "%" + filtro.getNomeRazao() + "%",
                isEmpty(filtro.getFantasiaSobreNome()) ? null : "%" + filtro.getFantasiaSobreNome() + "%",
                filtro.getIdentidade(),
                filtro.getDocumento(),
                filtro.getInscricaoMunicipal(),
                filtro.getInscricaoEstadual(),
                pages);

Enum

@Getter
public enum PessoaTipoEnum {

    FISICA("Física"), JURIDICA("Jurídica");

    private String descricao;

    PessoaTipoEnum(String descricao) {
        this.descricao = descricao;
    }

    public static PessoaTipoEnum buscaTipoEnum(String descricao) {
        for (PessoaTipoEnum enun : PessoaTipoEnum.values()) {
            if (enun.getDescricao().equals(descricao)) {
                return enun;
            }
        }
        return null;
    }
}

Soh para ter certeza, vc usou o @Nullable do pacote do spring?

Sim
import org.springframework.lang.Nullable;

Desculpe, mas é porque ele coloca na query assim: (pessoa0_.st_tipo_pessoa is null) mas quando for nulo isto não deveria nem aparecer na consulta

Vc já tentou com Query by Example?

Fiz assim e funcionou.

@Query(value = "SELECT p FROM Pessoa p WHERE (p.pessoaTipo = :pessoaTipo or :pessoaTipo is null) AND (p.nomeRazao = :nomeRazao or :nomeRazao is null) " +
            "AND (p.fantasiaSobreNome = :fantasiaSobreNome or :fantasiaSobreNome is null) AND (p.identidade = :identidade or :identidade is null) " +
            "AND (p.documento = :documento or :documento is null) AND (p.inscricaoMunicipal = :inscricaoMunicipal or :inscricaoMunicipal is null) " +
            "AND (p.inscricaoEstadual = :inscricaoEstadual or :inscricaoEstadual is null) ")
    Page<Pessoa> findByPessoaTipoAndNomeRazaoAndFantasiaSobreNomeAndIdentidadeAndDocumentoAndInscricaoMunicipalAndInscricaoEstadual(
            PessoaTipoEnum pessoaTipo,
            String nomeRazao,
            String fantasiaSobreNome,
            String identidade,
            String documento,
            String inscricaoMunicipal,
            String inscricaoEstadual,
            Pageable pageable);

Obrigado

1 curtida