I’m not able to log data into the database

Asked

Viewed 103 times

2

I’m a beginner in java and I have the following problem. On the state registration screen, I have a country selectOneMenu, and two fields for name and acronym.

When I go to 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

Follow 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;
    }

}

Cadastroestadobean

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;
    }

}

Cadastral

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 ()

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);
    }

}

Estadoconverter

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" inserir a descrição da imagem aqui

Table status created through "create" inserir a descrição da imagem aqui

Can you help me please?

  • Column 'pais_id' cannot be nul i.e., the value is going as null and it cannot be saved as such in your table

  • Absolutely Woton. The error occurs because of this. What I don’t understand is why it is returning null. I think the mapping is correct, but I can’t find why it’s going null.

  • When selecting the status in the selectonemenu, check if it is coming with id filled.

3 answers

2

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

Column 'pais_id' cannot be null

But I don’t see in your code you declaring that column with that name

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

And being 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 called id and a call pais_id, very likely to have, so you delete this table and generate again.

If possible post the generated table as well. Editing as per 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.");
  • Hi Edjane, but the country is saving. What is not saving is the value of the faths_id in the state table, in the relation @Manytoone.

  • What I don’t understand is where you are declaring that the column name in the table is pais_id, I never actually generated a table in Hibernate without declaring the column name id, but I will edit the question with what I think you can do to fix this problem.

  • Hi Edjane, I created the table again using "create". In the country table it creates the id, name, acronym. And in the state table, it creates id, name, acronym and faths_id. So I guess it’s not the problem of the "name" property, because otherwise I wouldn’t even create the table correctly. What do you think?

  • Yes, by what you put it created the table correctly, you made the changes I said? Did you take this to save(state)? A tip, you are working with frameworks and in this "world" things have to be well "married", make the changes, because I did not see other problems in your code other than the ones I spoke.

1

Your problem is possibly here:

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

The column pais_id is not referenced at any time in its mapping, so it is not mapped and therefore not filled in at the time of data recording. How she has a Constraint cannot be null, error occurs.

Experiment add name = "pais_id" in the annotation of @JoinColumn and see if the mistake stops happening.

  • I will try but I believe that the default name of @jointcolumn is the name of the object plus _id. In this case, as I did not put anything, he is using the name pais_id.

0


Just to record that I just found the error in the.xhtml registration file, in selectOneMenu.

Was:

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

Should be:

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.