Problema em Atualizar datatable no Primefaces

Tecnologias utilizadas: JSF com Primefaces (7), Hibernate, Bootstrap, Tomcat (8.45), Maven, mySQL Workbench (8.0) e o Netbeans.

Problema:

Quando adicionado, excluído ou restaurado algum item da tabela ocorre uma inconsistência que permite o item retornar, sair ou variar na tabela ao atualizar a página mesmo que no banco de dados o procedimento tenha sido concretizado.

A inconsistência ocorre mais precisamente após alguma alteração e só normaliza após iniciar novamente o projeto no servidor.

Video com o problema em ação: https://youtu.be/6jSkM08cK3U

O que já tentei:

  • Mudar o escopo da bean para Session, Request, Conversation e Application ao invés de View.
  • Instaciar nova lista e carrega-la com os itens do Banco logo após o inserir, remover, excluir ou restaurar, na Bean.
  • Nos respectivos commandbutton coloquei o update="IdDoDataTable" , update="IdDoFormulário:IdDoDataTable" , update="@Form" , update="@all" , junto com o update e sem o update eu tentei: process="@this" , process="IdDoDataTable" , tentei tudo isso com o ajax="true/false" , coloquei o action e o actionListener no botão também, assim como coloquei o oncomplete="listaComOsItens" .
  • Abrir no eclipse.
  • Chamar a consulta ao banco no postconstruct.

Observações:

  • Sou iniciante em Java, este projeto foi um trabalho academico já devidamente avaliado que pretendo transformar em portfólio.
  • Não há erros na saída do Tomcat.
  • As consultas são feitas normalmente após as mudanças de páginas, conforme informa o hibernate na saída do tomcat.
  • Código completo no GitHub: https://github.com/victorramide/SISSAJSF.git
  • Caso alguem realize o clone do projeto, é necessário adicionar manualmente um usuário no banco.

Código Bean:

package bean;
import dao.PedidoDAO;
import database.Pedido;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;


@javax.faces.view.ViewScoped
@ManagedBean
public class PedidoBean implements Serializable {

private Pedido pedido;
private List<Pedido> pedidosComuns;
private List<Pedido> pedidosPrioridade;
private List<Pedido> pedidosSentencasComuns;
private List<Pedido> pedidosSentencasPrioridade;
private List<Pedido> pedidosRemovidos;
private PedidoDAO pedidoDAO;

@PostConstruct
public void Init() {
    pedido = new Pedido();
    pedidoDAO = new PedidoDAO();
    pedidosComuns = new ArrayList<>();
    pedidosPrioridade = new ArrayList<>();
    pedidosSentencasComuns = new ArrayList<>();
    pedidosSentencasPrioridade = new ArrayList<>();
    pedidosRemovidos = new ArrayList<>();

}

public void salvar() {
    dataAtual();
    pedidoDAO.save(pedido);
    pedido = new Pedido();
}

public void excluirPedido(Long id) {
    Pedido p = pedidoDAO.delete(id);
    if (p != null) {
        pedido = p;
    }
}

public void removerPedido(Long id) {
    pedidoDAO.removerPedido(id);
}

public void restaurarPedido(Long id) {
    pedidoDAO.restaurarPedido(id);
}

public void dataAtual() {
    Date data = new Date();
    if (pedido.getDataConclusao() == null) {
        pedido.setDataConclusao(data);
    }
}

public Pedido getPedido() {
    return pedido;
}

public void setPedido(Pedido pedido) {
    this.pedido = pedido;
}

public List<Pedido> getPedidosComuns() {
    pedidosComuns = pedidoDAO.listaPedidoComum();
    return pedidosComuns;
}

public void setPedidosComuns(List<Pedido> processosComum) {
    this.pedidosComuns = processosComum;
}

public List<Pedido> getPedidosPrioridade() {
    pedidosPrioridade = pedidoDAO.listaPedidoPrioridade();
    return pedidosPrioridade;
}

public void setPedidosPrioridade(List<Pedido> processosPrioridade) {
    this.pedidosPrioridade = processosPrioridade;
}

public List<Pedido> getPedidosSentencasComuns() {
    pedidosSentencasComuns = pedidoDAO.listaPedidoSentencaComum();
    return pedidosSentencasComuns;
}

public void setPedidosSentencasComuns(List<Pedido> sentencasComum) {
    this.pedidosSentencasComuns = sentencasComum;
}

public List<Pedido> getPedidosSentencasPrioridade() {
    pedidosSentencasPrioridade = pedidoDAO.listaPedidoSentencaPrioridade();
    return pedidosSentencasPrioridade;
}

public void setPedidosSentencasPrioridade(List<Pedido> sentencasPrioridade) {
    this.pedidosSentencasPrioridade = sentencasPrioridade;
}

public List<Pedido> getPedidosRemovidos() {
    pedidosRemovidos = pedidoDAO.listaPedidoRemovido();
    return pedidosRemovidos;
}

public void setPedidosRemovidos(List<Pedido> pedidosExcluidos) {
    this.pedidosRemovidos = pedidosExcluidos;
}

public PedidoDAO getPedidoDAO() {
    return pedidoDAO;
}

public void setPedidoDAO(PedidoDAO pedidoDAO) {
    this.pedidoDAO = pedidoDAO;
}
}

Codigo da View:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:decorate xmlns="http://www.w3.org/1999/xhtml"
         xmlns:h="http://xmlns.jcp.org/jsf/html"
         xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
         xmlns:p="http://primefaces.org/ui"
         template="template.xhtml"
         xmlns:f="http://xmlns.jcp.org/jsf/core"
         xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">

<div id="lista-pedidos">
    <div class="container">
        <div class="jumbotron">
            <h1><center>Lista de Pedidos</center></h1>
            <p>
                <br/><h2>Processos comuns</h2><br/>
                <h:form id="formTable1">
                    <p:dataTable var="pedido1" value="#{pedidoBean.pedidosComuns}" id="tabela1" rowIndexVar="rowIndex" resizableColumns="true">
                        <p:column headerText="#" style="width: 4%">
                            <center> #{rowIndex+1} </center>
                        </p:column> 
                        <p:column headerText="Processo">
                            <center> <h:outputText value="#{pedido1.numeroProcesso}" /></center>
                        </p:column> 
                        <p:column headerText="Classe">
                            <center> <h:outputText value="#{pedido1.classe}" /></center>
                        </p:column>    
                        <p:column headerText="Tipo">
                            <center><h:outputText value="#{pedido1.tipo}" /></center>
                        </p:column>
                        <p:column headerText="OAB">
                            <center>  <h:outputText value="#{pedido1.oab}" /></center>
                        </p:column>
                        <p:column headerText="Remover" rendered="#{usuarioBean.usuario.logado == true}" style="width: 25%">
                            <center>
                                <p:inputText value="#{pedido1.justificativa}" placeholder="Justifique" style="width: 75%" />
                                <p:commandButton icon="ui-icon-trash" title="Excluir" ajax="true" action="#{pedidoBean.removerPedido(pedido1.id)}" update=":formTable1:tabela1"/>
                            </center>
                        </p:column>
                    </p:dataTable>
                </h:form>
            </p>
            <p>
                <br/><h2>Processos prioridade</h2><br/>
                <h:form id="formTable2">
                    <p:dataTable var="pedido2" value="#{pedidoBean.pedidosPrioridade}" id="tabela2" rowIndexVar="rowIndex" resizableColumns="true">
                        <p:column headerText="#" style="width: 4%">
                            <center> #{rowIndex+1} </center>
                        </p:column> 
                        <p:column headerText="Processo">
                            <center> <h:outputText value="#{pedido2.numeroProcesso}" /></center>
                        </p:column> 
                        <p:column headerText="Classe">
                            <center><h:outputText value="#{pedido2.classe}" /></center>
                        </p:column>    
                        <p:column headerText="Tipo">
                            <center><h:outputText value="#{pedido2.tipo}" /></center>
                        </p:column>
                        <p:column headerText="OAB">
                            <center><h:outputText value="#{pedido2.oab}" /></center>
                        </p:column>
                        <p:column headerText="Remover" rendered="#{usuarioBean.usuario.logado == true}" style="width: 25%">
                            <center>
                                <p:inputText value="#{pedido2.justificativa}" placeholder="Justifique" style="width: 75%" />
                                <p:commandButton icon="ui-icon-trash" title="Excluir" ajax="true" action="#{pedidoBean.removerPedido(pedido2.id)}" update=":formTable2:tabela2"/>
                            </center>
                        </p:column>
                    </p:dataTable>
                </h:form>
            </p>
            <p>
                <br/><h2>Processos sentenças comuns</h2><br/>
                <h:form id="formTable3">
                    <p:dataTable var="pedido3" value="#{pedidoBean.pedidosSentencasComuns}" id="tabela3" rowIndexVar="rowIndex" resizableColumns="true">
                        <p:column headerText="#" style="width: 4%">
                            <center> #{rowIndex+1} </center>
                        </p:column> 
                        <p:column headerText="Processo">
                            <center><h:outputText value="#{pedido3.numeroProcesso}" /></center>
                        </p:column> 
                        <p:column headerText="Classe">
                            <center><h:outputText value="#{pedido3.classe}" /></center>
                        </p:column>    
                        <p:column headerText="OAB">
                            <center><h:outputText value="#{pedido3.oab}" /></center>
                        </p:column>
                        <p:column headerText="Conclusão">
                            <center><h:outputText value="#{pedido3.dataConclusao}" /></center>
                        </p:column>
                        <p:column headerText="Remover" rendered="#{usuarioBean.usuario.logado == true}" style="width: 25%">
                            <center>
                                <p:inputText value="#{pedido3.justificativa}" placeholder="Justifique" style="width: 75%" />
                                <p:commandButton icon="ui-icon-trash" title="Excluir" ajax="true" action="#{pedidoBean.removerPedido(pedido3.id)}" update=":formTable3:tabela3"/>
                            </center>
                        </p:column>
                    </p:dataTable>
                </h:form>
            </p>
            <p>
                <br/><h2>Processos sentenças prioridade</h2><br/>
                <h:form id="formTable4">
                    <p:dataTable var="pedido4" value="#{pedidoBean.pedidosSentencasPrioridade}" id="tabela4" rowIndexVar="rowIndex" resizableColumns="true">
                        <p:column headerText="#" style="width: 4%">
                            <center> #{rowIndex+1} </center>
                        </p:column> 
                        <p:column headerText="Processo">
                            <center><h:outputText value="#{pedido4.numeroProcesso}"/></center>
                        </p:column> 
                        <p:column headerText="Classe">
                            <center><h:outputText value="#{pedido4.classe}" /></center>
                        </p:column>    
                        <p:column headerText="OAB">
                            <center><h:outputText value="#{pedido4.oab}"/></center>
                        </p:column>
                        <p:column headerText="Conclusão">
                            <center><h:outputText value="#{pedido4.dataConclusao}" /></center>
                        </p:column>
                        <p:column headerText="Remover" rendered="#{usuarioBean.usuario.logado == true}" style="width: 25%">
                            <center>
                                <p:inputText value="#{pedido4.justificativa}" placeholder="Justifique" style="width: 75%" />
                                <p:commandButton icon="ui-icon-trash" title="Excluir" ajax="true" action="#{pedidoBean.removerPedido(pedido4.id)}" update=":formTable4:tabela4"/>
                            </center>
                        </p:column>
                    </p:dataTable>
                </h:form>
            </p>
        </div>
    </div>
</div>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:decorate xmlns="http://www.w3.org/1999/xhtml"
         xmlns:h="http://xmlns.jcp.org/jsf/html"
         xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
         template="template.xhtml"
         xmlns:p="http://primefaces.org/ui"
         xmlns:f="http://xmlns.jcp.org/jsf/core">

<div id="lista-pedidos" >
    <div class="container">
        <div class="jumbotron" >
            <br/><h1><center>Lista de pedidos excluídos da lista</center></h1><br/>
            <p>
                <h:form id="formTable">
                    <p:dataTable var="excluido" value="#{pedidoBean.pedidosRemovidos}" id="tabela5"  rowIndexVar="rowIndex" >
                        <p:column headerText="#" style="width: 4%">
                           <center> #{rowIndex+1} </center>
                        </p:column> 
                        <p:column headerText="Processo">
                            <center><h:outputText value="#{excluido.numeroProcesso}" /></center>
                        </p:column> 
                        <p:column headerText="Tipo">
                            <center><h:outputText value="#{excluido.tipo}" /></center>
                        </p:column>
                        <p:column headerText="OAB">
                            <center><h:outputText value="#{excluido.oab}"/></center>
                        </p:column>
                        <p:column headerText="Justificativa">
                            <center><h:outputText value="#{excluido.justificativa}" style="font-size: small" /></center>
                        </p:column>
                        <p:column headerText="Remover" rendered="#{usuarioBean.usuario.logado == true}" >
                            <center>
                                <p:commandButton icon="ui-icon-arrowreturnthick-1-w" title="restaurar" ajax="true" action="#{pedidoBean.restaurarPedido(excluido.id)}" update=":formTable:tabela5" />
                                <p:commandButton icon="ui-icon-trash" title="Excluir" ajax="true" action="#{pedidoBean.excluirPedido(excluido.id)}" update=":formTable:tabela5"/>
                            </center>
                        </p:column>
                    </p:dataTable>
                </h:form>
            </p>
        </div>
    </div>
</div>

Código Database:

package database;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "tb_pedido")
public class Pedido implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;

@Column(name = "numeroProcesso", length = 25, nullable = false)
private String numeroProcesso;

@Column(name = "classe")
private String classe;

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

@Column(name = "prioridade")
private boolean prioridade;

@Column(name = "excluido")
private boolean excluido;

@Column(name = "justificativa")
private String justificativa;

@Column(name = "oab", nullable = false)
private String oab;

@Column(name = "dataConclusao")
@Temporal(TemporalType.DATE)
private Date dataConclusao;

public long getId() {
    return id;
}

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

public String getNumeroProcesso() {
    return numeroProcesso;
}

public void setNumeroProcesso(String numeroProcesso) {
    this.numeroProcesso = numeroProcesso;
}

public String getClasse() {
    return classe;
}

public void setClasse(String classe) {
    this.classe = classe;
}

public String getTipo() {
    return tipo;
}

public void setTipo(String tipo) {
    this.tipo = tipo;
}

public boolean isPrioridade() {
    return prioridade;
}

public void setPrioridade(boolean prioridade) {
    this.prioridade = prioridade;
}

public boolean isExcluido() {
    return excluido;
}

public void setExcluido(boolean excluido) {
    this.excluido = excluido;
}

public String getJustificativa() {
    return justificativa;
}

public void setJustificativa(String justificativa) {
    this.justificativa = justificativa;
}

public String getOab() {
    return oab;
}

public void setOab(String oab) {
    this.oab = oab;
}

public Date getDataConclusao() {
    return dataConclusao;
}

public void setDataConclusao(Date dataConclusao) {
    this.dataConclusao = dataConclusao;
}
}

Hibernate DAO:

package dao;
import database.Pedido;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public class PedidoDAO extends GenericDAO<Pedido, Long> {

public PedidoDAO() {
    super(Pedido.class);
}

public List<Pedido> listaPedidoComum() {
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.or(Restrictions.eq("tipo", "despacho"), Restrictions.eq("tipo", "decisao")));
    criteria.add(Restrictions.eq("prioridade", false));
    criteria.add(Restrictions.eq("excluido", false));
    return criteria.list();
}

public List<Pedido> listaPedidoPrioridade() {
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.or(Restrictions.eq("tipo", "despacho"), Restrictions.eq("tipo", "decisao")));
    criteria.add(Restrictions.eq("prioridade", true));
    criteria.add(Restrictions.eq("excluido", false));
    return criteria.list();
}

public List<Pedido> listaPedidoSentencaComum() {
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.eq("tipo", "sentenca"));
    criteria.add(Restrictions.eq("prioridade", false));
    criteria.add(Restrictions.eq("excluido", false));
    criteria.addOrder(Order.asc("dataConclusao"));
    return criteria.list();
}

public List<Pedido> listaPedidoSentencaPrioridade() {
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.eq("tipo", "sentenca"));
    criteria.add(Restrictions.eq("prioridade", true));
    criteria.add(Restrictions.eq("excluido", false));
    criteria.addOrder(Order.asc("dataConclusao"));
    return criteria.list();
}

public List<Pedido> listaPedidoRemovido() {
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.eq("excluido", true));
    return criteria.list();
}

public Pedido removerPedido(Long id) {
    Pedido retorno = null;
    org.hibernate.Session session = dao.HibernateUtil.getSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        retorno = (Pedido) session.get(Pedido.class, id);
        retorno.setExcluido(true);
        session.update(retorno);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return retorno;
}
public Pedido restaurarPedido(Long id) {
    Pedido retorno = null;
    org.hibernate.Session session = dao.HibernateUtil.getSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        retorno = (Pedido) session.get(Pedido.class, id);
        retorno.setJustificativa("");
        retorno.setExcluido(false);
        session.update(retorno);
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return retorno;
}

public Long contarOabListaComum(String oab){
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.or(Restrictions.eq("tipo", "despacho"), Restrictions.eq("tipo", "decisao")));
    criteria.add(Restrictions.eq("prioridade", false));
    criteria.add(Restrictions.eq("excluido", false));
    criteria.setProjection(Projections.rowCount());  
    return (Long) criteria.uniqueResult();
}

public Long contarOabListaPrioridade(String oab){
    Session sessao = dao.HibernateUtil.getSession();
    Criteria criteria = sessao.createCriteria(Pedido.class);
    criteria.add(Restrictions.or(Restrictions.eq("tipo", "despacho"), Restrictions.eq("tipo", "decisao")));
    criteria.add(Restrictions.eq("prioridade", true));
    criteria.add(Restrictions.eq("excluido", false));
    criteria.setProjection(Projections.rowCount());  
    return (Long) criteria.uniqueResult();
}

}

Escolhe uma das opcoes:

  • nao usar Hibernate. ja que nao quer hibernar dados, seria desnecessário, menos uma dependencia grande no projeto
  • abrir e fechar a session a cada requisicao
  • usar statelessession