Error refreshing table in XHTML (Primefaces JavaWeb)

3

I have a problem loading a table from a MySQL database. The table is in PrimeFaces and loads the data from the database when I deploy the application. But when I modify a data, even though it loads it into the database, it does not show it in the table.

Edited

Here something of the code .. it does not work for me with the property refresh through the commandbutton ..

<p:panel id="tabla" style="width: 100% ; font-size: small; text-align: left ; border : none ;"  > 
    <p:dataTable style="border : none ;"
                 id="tablePro" var="programacion" value="#{mantenimientoTvista.listaProgramaciontodo}" rows="10"
                 paginator="true"
                 paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                 rowsPerPageTemplate="5,10,15"
                 filteredValue="#{mantenimientoTvista.listaProgramaciontodo}"
                 emptyMessage="No se encontraron resultados"
                 selectionMode="single"
                 rowKey="#{programacion.idprogramacion}"
                 selection="#{mantenimientoTvista.programacionSeleccionado}"
                 >
        <p:ajax event="rowSelect" listener="#{mantenimientoTvista.funcionSeleccionarProd}" update="forma:growl ,:forma:campos" />

        <p:column headerText="nombre tecnico" width="30" filterBy="#{programacion.documentotecnico.personal.nombrepersonal}">
            <h:outputText value="#{programacion.documentotecnico.personal.nombrepersonal}"/>
        <p:column headerText="Tipo mant" width="5" filterBy="#{programacion.idclase.clasenombre}" filterMatchMode="contains">
            <h:outputText value="#{programacion.idclase.clasenombre}"/>
        </p:column>      
    </p:dataTable>

</p:panel>

and this is the button I leave the code here apart ------------------------------------- ---

and here the value code of technicallist (I omit many columns so as not to paste a code too long, I just need to refresh the name of the technician when I change it in the table).

This is an entity class from the database ..

@Entity
@Table(name = "personal")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Personal.findAll", query = "SELECT p FROM Personal p"),
    @NamedQuery(name = "Personal.findByDocumentopersonal", query = "SELECT p FROM Personal p WHERE p.documentopersonal = :documentopersonal"),
    @NamedQuery(name = "Personal.findByApellidopersonal", query = "SELECT p FROM Personal p WHERE p.apellidopersonal = :apellidopersonal"),
    @NamedQuery(name = "Personal.findByClavepersonal", query = "SELECT p FROM Personal p WHERE p.clavepersonal = :clavepersonal"),
    @NamedQuery(name = "Personal.findByNombrepersonal", query = "SELECT p FROM Personal p WHERE p.nombrepersonal = :nombrepersonal")})
public class Personal implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "documentopersonal")
    private Long documentopersonal;
    @Size(max = 255)
    @Column(name = "apellidopersonal")
    private String apellidopersonal;
    @Size(max = 255)
    @Column(name = "clavepersonal")
    private String clavepersonal;
    @Size(max = 255)
    @Column(name = "nombrepersonal")
    private String nombrepersonal;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "personal")
    private Administrador administrador;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "personal")
    private Tecnicos tecnicos;

    public Personal() {
    }

    public Personal(Long documentopersonal) {
        this.documentopersonal = documentopersonal;
    }

    public Long getDocumentopersonal() {
        return documentopersonal;
    }

    public void setDocumentopersonal(Long documentopersonal) {
        this.documentopersonal = documentopersonal;
    }

    public String getApellidopersonal() {
        return apellidopersonal;
    }

    public void setApellidopersonal(String apellidopersonal) {
        this.apellidopersonal = apellidopersonal;
    }

    public String getClavepersonal() {
        return clavepersonal;
    }

    public void setClavepersonal(String clavepersonal) {
        this.clavepersonal = clavepersonal;
    }

    public String getNombrepersonal() {
        return nombrepersonal;
    }

    public void setNombrepersonal(String nombrepersonal) {
        this.nombrepersonal = nombrepersonal;
    }

    public Administrador getAdministrador() {
        return administrador;
    }

    public void setAdministrador(Administrador administrador) {
        this.administrador = administrador;
    }

    public Tecnicos getTecnicos() {
        return tecnicos;
    }

    public void setTecnicos(Tecnicos tecnicos) {
        this.tecnicos = tecnicos;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (documentopersonal != null ? documentopersonal.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Personal)) {
            return false;
        }
        Personal other = (Personal) object;
        if ((this.documentopersonal == null && other.documentopersonal != null) || (this.documentopersonal != null && !this.documentopersonal.equals(other.documentopersonal))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.simap.modelo.Personal[ documentopersonal=" + documentopersonal + " ]";
    }        

}
    
asked by edwar fuentes 07.06.2016 в 21:24
source

4 answers

4

It is a very frequent and annoying problem. This is called stale data . It usually occurs when you are not operating within a transaction and the EntityManager uses a cached version of the query. You have several options.

EntityManager # refresh

Calling the method refresh of EntityManager refreshes the state of the entity, forcing it to always get the latest version of it.

em.refresh(objeto);

EntityManagerFactory # getCache # evictAll

Another option is to call the method getCache() of the EntityManagerFactory and clean the cache using evictAll() , before obtaining records.

em.getEntityManagerFactory().getCache().evictAll();

Use a transaction

This is the most recommended. Do not comment if you have a full profile server or just a servlet container like Tomcat or Jetty. However, with both you can make your queries in transactions.

Jetty or Tomcat

EntityTransaction tx = null;
try {
    tx = em.getTransaction();
    tx.begin(); // empiezas la transacción
    // tu lógica aquí
    tx.commit(); // finalizas la transacción
} catch (PersistenceException e) {
    // si algo sale mal, hacemos rollback para revertir cambios
    if(tx != null && tx.isActive()) {
       tx.rollback();
    }
} finally {
    em.close();
}

WildFly, GlassFish, etc.

In this type of servers you do not need the above because they are already managed by JTA. For example, your services can be EJB's which are transactional to do your logic.

@Stateless
@LocalBean
public class UsuarioService implements Serializable {

   @PersistenceContext
   private EntityManager em;

   public List<Usuario> listar() {
       TypedQuery<Usuario> query = em.createNamedQuery(Usuario.FIND_ALL, Usuario.class);
       return query.getResultList();
   }
}

You can also deactivate your provider's cache in the persistence.xml :

<shared-cache-mode>NONE</share-cache-mode>

On the contrary, if what you have is a problem of refreshing data, notice that in the attribute update of commandButton you are putting a valid id. Remember that if the element to be updated is outside the form , you must prepend : to the id. For example:

<p:commandButton actionListener="#{tuBean.metodo()}" update=":tabla" />

Update

I have not seen anywhere your commandButton , what I see is a listener for row selection. In this listener you have a comma (,) which should not be in recent versions of JSF. You can render as many elements as you want just by separating them by spaces.

    
answered by 07.06.2016 / 22:30
source
2

If you use a command button you can assign the update property to the button to refresh the data table.

Example.

<p:commandButton actionListener="#{controlador.accion()}" 
                                                     update=":dataTableId"
                                                     icon="ui-icon-arrowrefresh-1-s"
                                                     title="Cargar Datos">
                                        <f:param name="parametro1" value="valor1"/>
                                        <f:param name="parametro2" value="valor2"/> 
</p:commandButton>
    
answered by 07.06.2016 в 23:14
1

What I do in these cases is that when I change the data, I reload the list, and the resulting list I refresh it with a method that I added in the AbstractFacade file (I work with NetBeans and it creates it automatically) when the session bean is added for the entities), the method code is as follows:

/**
 * Actualiza el listado cuando se ha hecho un cambio y no se refleja 
 * @param entityCollection
 * @return 
 */
public List<T> refreshCollection(List<T> entityCollection) {
    List<T> result = new ArrayList<>();
    if (entityCollection != null && !entityCollection.isEmpty()) {
        getEntityManager().getEntityManagerFactory().getCache().evict(entityCollection.get(0).getClass());
        T mergedEntity;
        for (T entity : entityCollection) {
            mergedEntity = getEntityManager().merge(entity);
            getEntityManager().refresh(mergedEntity);
            result.add(mergedEntity);
        }
    }
    return result;
}

Then after I load the list, I call that method:

public List<Entidad> cargarDatos() {
    Query q = em.createQuery("SELECT E FROM Entidad E");
    return refreshCollection(q.getResultList());
}

Do not forget to update the datatable so that changes are reflected after updating the list. In general that way I solve that problem.

Greetings.

    
answered by 12.10.2016 в 19:44
0

Well the solution I found ... I do not know why, it was to change a field of the table in the database (In my case an AI) so that I could refresh the data in the xhtml, I do not know why, I'm still looking for a more practical and efficient solution.

    
answered by 06.07.2016 в 22:57