I am not able to register data in the database

2

I'm a beginner in Java and I have the following problem. In the status register screen, I have a country selectOneMenu, and two fields for name and acronym.

When I save in the database I get the following error:

Console:

2018-05-24 01:16:53,033 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] Column 'pais_id' cannot be null

Here are my codes:

CadastroEstado.xhtml

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:p="http://primefaces.org/ui"
                xmlns:o="http://omnifaces.org/ui"
                template="/WEB-INF/template.xhtml">

    <ui:define name="title">#{cadastroEstadoBean.editando ? 'Edição de estado' : 'Novo estado'}</ui:define>

    <ui:define name="breadcrumb">
        <li>Pages</li>
        <li>/</li>
        <li><p:link outcome="/estados/cadastroEstado">Novo estado</p:link></li>
    </ui:define>

    <ui:define name="content">
        <f:metadata>
            <f:event listener="#{cadastroEstadoBean.inicializar()}" type="preRenderView" />
            <o:viewParam name="estado" value="#{cadastroEstadoBean.estado}" />
        </f:metadata>

        <h:form>
            <h1>#{cadastroEstadoBean.editando ? 'Edição de estado' : 'Novo estado'}</h1>

            <p:messages autoUpdate="true" closable="true" />

            <p:toolbar style="margin-top: 10px">
                <p:toolbarGroup>
                    <p:button value="Novo" outcome="/estados/cadastroEstado" />
                    <p:commandButton id="botaoSalvar" value="Salvar" action="#{cadastroEstadoBean.salvar()}" update="@form" />
                </p:toolbarGroup>

                <p:toolbarGroup align="right">
                    <p:button value="Pesquisar" outcome="/estados/pesquisaEstado" />
                </p:toolbarGroup>
            </p:toolbar>

            <p:panelGrid columns="2" id="painel"
                style="width: 100%; margin-top: 15px" columnClasses="rotulo, campo">

                <p:outputLabel value="País" for="pais"/>
                <p:selectOneMenu id="pais" value="#{cadastroEstadoBean.pais}" >
                    <f:selectItem itemLabel="Selecione o país"/>
                    <f:selectItems value="#{cadastroEstadoBean.listaPaises}" var="pais"
                        itemValue="#{pais}" itemLabel="#{pais.nome}" />
                </p:selectOneMenu>

                <p:outputLabel for="nome" value="Nome" />
                <p:inputText id="nome" size="45" maxlength="50" value="#{cadastroEstadoBean.estado.nome}" />

                <p:outputLabel for="sigla" value="Sigla" />
                <p:inputText id="sigla" size="10" maxlength="10" value="#{cadastroEstadoBean.estado.sigla}" />

            </p:panelGrid>
        </h:form>
    </ui:define>

</ui:composition>

State

package com.damasystem.dama.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "estado")
public class Estado implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String nome;
    private String sigla;
    private Pais pais;

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(nullable = false, length = 30)
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Column(nullable = false, length = 2)
    public String getSigla() {
        return sigla;
    }

    public void setSigla(String sigla) {
        this.sigla = sigla;
    }

    @ManyToOne
    @JoinColumn(nullable = false)
    public Pais getPais() {
        return pais;
    }

    public void setPais(Pais pais) {
        this.pais = pais;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Estado other = (Estado) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }


}

Parents

package com.damasystem.dama.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "pais")
public class Pais implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String nome;
    private String sigla;
    private List<Estado> estados = new ArrayList<>();

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(nullable = false, length = 30)
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Column(nullable = false, length = 3)
    public String getSigla() {
        return sigla;
    }

    public void setSigla(String sigla) {
        this.sigla = sigla;
    }

    @OneToMany(mappedBy = "pais", cascade = CascadeType.ALL)
    public List<Estado> getEstados() {
        return estados;
    }

    public void setEstados(List<Estado> estados) {
        this.estados = estados;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Pais other = (Pais) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

SignatureBean

package com.damasystem.dama.controller;

import java.io.Serializable;
import java.util.List;

import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import com.damasystem.dama.model.Estado;
import com.damasystem.dama.model.Pais;
import com.damasystem.dama.repository.Paises;
import com.damasystem.dama.service.CadastroEstadoService;
import com.damasystem.dama.util.jsf.FacesUtil;

@Named
@ViewScoped
public class CadastroEstadoBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Estado estado;

    private Pais pais;
    private Pais paisSelecionado;

    @Inject
    private CadastroEstadoService cadastroEstadoService;

    @Inject
    private Paises repositorioPaises;

    private List<Pais> listaPaises;

    public CadastroEstadoBean() {
        limpar();
    }

    public void inicializar() {
        if (this.estado == null) {
            limpar();
        }
        listaPaises = repositorioPaises.paises();
    }

    private void limpar() {
        estado = new Estado();
        pais = new Pais();
        listaPaises = null;

    }

    public boolean isEditando() {
        return this.estado.getId() != null;
    }

    public void salvar() {
        this.estado = cadastroEstadoService.salvar(this.estado);
        limpar();

        FacesUtil.addInfoMessage("Estado salvo com sucesso.");
    }

    public Estado getEstado() {
        return estado;
    }

    public void setEstado(Estado estado) {
        this.estado = estado;
    }

    public Pais getPais() {
        return pais;
    }

    public void setPais(Pais pais) {
        this.pais = pais;
    }

    public Pais getPaisSelecionado() {
        return paisSelecionado;
    }

    public void setPaisSelecionado(Pais paisSelecionado) {
        this.paisSelecionado = paisSelecionado;
    }

    public List<Pais> getListaPaises() {
        return listaPaises;
    }

}

Registration StatusService

package com.damasystem.dama.service;

import java.io.Serializable;

import javax.inject.Inject;

import com.damasystem.dama.model.Estado;
import com.damasystem.dama.repository.Estados;
import com.damasystem.dama.util.jpa.Transactional;

public class CadastroEstadoService implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private Estados estados;

    @Transactional
    public Estado salvar(Estado estado) {
        Estado estadoExistente = estados.porNome(estado.getNome());

        if(estadoExistente != null && !estadoExistente.equals(estado)) {
            throw new NegocioException("Já existe um estado com o nome informado.");
        }

        return estados.guardar(estado);
    }

}

States (repository)

package com.damasystem.dama.repository;

import java.io.Serializable;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import com.damasystem.dama.model.Estado;

public class Estados implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private EntityManager manager;

    public Estado guardar(Estado estado) {
        return estado = manager.merge(estado);
    }

    public Estado porNome(String nome) {
        try {
            return manager.createQuery("from Estado where upper(nome) = :nome", Estado.class)
                    .setParameter("nome", nome.toUpperCase())
                    .getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    public Estado porId(Long id) {
        return manager.find(Estado.class, id);
    }

}

StatusConverter

package com.damasystem.dama.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import com.damasystem.dama.model.Estado;
import com.damasystem.dama.repository.Estados;

@FacesConverter(forClass = Estado.class)
public class EstadoConverter implements Converter {

    @Inject
    private Estados estados;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        Estado retorno = null;

        if (StringUtils.isNotEmpty(value)) {
            Long id = new Long(value);
            retorno = estados.porId(id);
        }

        return retorno;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value != null) {
            Estado estado = (Estado) value;
            return estado.getId() == null ? null : estado.getId().toString();
        }

        return "";
    }


}

Parent table created through "create"

Statustablecreatedthrough"create"

Can you help me please?

    
asked by anonymous 24.05.2018 / 06:51

3 answers

0

Just to register that I just found the error in the file Status.xhtml, in the selectOneMenu.

It was:

<p:selectOneMenu id="pais" value="#{cadastroEstadoBean.pais}" >

Should be:

<p:selectOneMenu id="pais" value="#{cadastroEstadoBean.estado.pais}" >
    
25.05.2018 / 04:18
2

What I think is happening in your code is that you must have generated a table before with different data, because this is why analyzing the error it returns:

Column 'pais_id' cannot be null

But I do not see in your code declaring this column with that name

@Id
@GeneratedValue
public Long getId() {
   return id;
}

And because I am informed that this column exists in your database, I believe that at some point you have done this:

@Id
@GeneratedValue
@Column(name = "pais_id")
public Long getId() {
   return id;
}

My tip is, check if your table has a column named id and a pais_id call, most likely to have, then you delete that table and regenerate.

If possible put the generated table as well. Editing by comment. In your Parents class, make the following change:

 ...   
@Id
@GeneratedValue
@Column(name = "pais_id")
  public Long getId() {
  return id;
}
    ...

And in your State class, you do the following:

...
@ManyToOne
@JoinColumn(name = "pais_id", nullable = false)
public Pais getPais() {
   return pais;
}
...

Edit your Bean save method

public void salvar() {
  this.estado = cadastroEstadoService.salvar(estado); //tira o this de estado
  limpar();
  FacesUtil.addInfoMessage("Estado salvo com sucesso.");
    
24.05.2018 / 12:14
1

Your problem is possibly here:

@ManyToOne
@JoinColumn(nullable = false)
public Pais getPais() {
     return pais;
}

The pais_id column is not referenced at any point in your mapping, so it is not mapped and therefore not filled at the time of writing the data. Since it has a constraint of not being able to be null, the error occurs.

I try to add name = "pais_id" to the annotation of @JoinColumn and see if the error stops happening.

    
24.05.2018 / 13:04