我在使用PrimeFaces 3.4.1和JSF 2.1.6的dataTable时遇到以下问题。第一次加载页面时,dataTable会填充来自我们数据库的数据,但只要在页面上执行操作(编辑链接,dataTable排序或过滤),dataTable就会丢失其数据。 DataTable包含此类中的元素:
package es.cne.sicbios.entities.tramites.envios;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataContactoEconomico;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataEmpresaFilial;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataHistoricoTipoSujeto;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataPersonaContacto;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataPlantaProduccion;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataRepresentante;
import es.cne.sicbios.entities.tramites.envios.sujeto.data.EnvioDataSujeto;
import es.cne.sicbios.entities.tramites.solicitudes.SolicitudSujeto;
@SuppressWarnings("serial")
@Entity
public class EnvioSujeto extends Envio implements Serializable{
@ManyToOne(optional = false, cascade = CascadeType.ALL)
private SolicitudSujeto solicitud;
@OneToOne(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private EnvioDataContactoEconomico envioDataContactoEconomico;
@OneToMany(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private List<EnvioDataEmpresaFilial> enviosDataEmpresaFilial;
@OneToMany(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private List<EnvioDataHistoricoTipoSujeto> enviosDataHistoricoTipoSujeto;
@OneToMany(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private List<EnvioDataPlantaProduccion> enviosDataPlantaProduccion;
@OneToOne(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private EnvioDataSujeto envioDataSujeto;
@OneToMany(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private List<EnvioDataPersonaContacto> enviosDataPersonaContacto;
@OneToMany(mappedBy = "envioSujeto", cascade = CascadeType.ALL)
private List<EnvioDataRepresentante> enviosDataRepresentante;
public SolicitudSujeto getSolicitud() {
return solicitud;
}
public void setSolicitud(final SolicitudSujeto solicitud) {
this.solicitud = solicitud;
}
... //rest of getters and setters
}
在对dataTable执行操作后进行调试时,我们仅将数据保存在envioDatasujeto字段中,元素上的每个其他数据都将丢失。
这是xhtml:
<ui:composition template="/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:blb="http://ecb.bilbomatica.es/components">
<ui:define name="content">
<f:loadBundle basename="es.cne.sicbios.gestionsujetos" var="gestionmsg" />
<h:form id="formulario">
<p:messages id="messages" showDetail="true" autoUpdate="true"
closable="true" />
<p:dataTable var="envioSujeto"
value="#{listadoEnviosSujetoMB.lazyListaAllEnvios}"
paginator="true" rows="10"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15"
selectionMode="single"
selection="#{listadoEnviosSujetoMB.envioSeleccionado}"
id="listaEnviosSujetos"
lazy="true">
<f:facet name="header">
#{gestionmsg.txt_listadoEnviosSujetos}
</f:facet>
<p:column sortBy="#{envioSujeto.envioDataSujeto.datosSujeto.acronimo}" headerText="#{gestionmsg.column_acronimo}"
filterBy="#{envioSujeto.envioDataSujeto.datosSujeto.acronimo}">
<h:outputText value="#{envioSujeto.envioDataSujeto.datosSujeto.acronimo}" />
</p:column>
<p:column sortBy="#{envioSujeto.solicitud.id}"
headerText="#{gestionmsg.column_id_tramite}"
filterBy="#{envioSujeto.solicitud.id}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.solicitud.id}" />
</p:column>
<p:column sortBy="#{envioSujeto.fechaCreacion.time}"
headerText="#{gestionmsg.column_fechaCreacion}"
filterBy="#{envioSujeto.fechaCreacion.time}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.fechaCreacion.time}" >
<f:convertDateTime pattern="dd/mm/yyyy"/>
</h:outputText>
</p:column>
<p:column sortBy="#{envioSujeto.tipo}"
headerText="#{gestionmsg.column_tipoEnvio}"
filterBy="#{envioSujeto.tipo}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.tipo}" />
</p:column>
<p:column sortBy="#{envioSujeto.solicitud.estado}"
headerText="#{gestionmsg.column_estado}"
filterBy="#{envioSujeto.solicitud.estado}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.solicitud.estado}" />
</p:column>
<p:column sortBy="#{envioSujeto.idRegistro}"
headerText="#{gestionmsg.column_idRegistro}"
filterBy="#{envioSujeto.idRegistro}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.idRegistro}" />
</p:column>
<p:column sortBy="#{envioSujeto.id}"
headerText="id"
filterBy="#{envioSujeto.id}"
filterMatchMode="contains">
<h:outputText value="#{envioSujeto.id}" />
</p:column>
<ui:remove>
<!--
<p:column
headerText="#{gestionmsg.column_bloqueo}"
>
<h:outputText value="" />
</p:column>
-->
</ui:remove>
</p:dataTable>
<p:commandLink icon="ui-icon-pencil"
update=":formulario"
actionListener="#{listadoEnviosSujetoMB.goToEditarEnvio}" >
<h:outputText value="Editar" />
</p:commandLink>
</h:form>
</ui:define>
</ui:composition>
它的托管bean:
package es.cne.sicbios.managedbean.gestionsujetos;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import es.cne.sicbios.entities.tramites.envios.Envio;
import es.cne.sicbios.services.tramites.envios.IEnvioService;
import es.cne.sicbios.utils.FacesUtils;
@SuppressWarnings("serial")
@ViewScoped
@ManagedBean(name = "listadoEnviosSujetoMB")
public class ListadoEnviosSujetoMB implements Serializable {
@ManagedProperty(value = "#{envioSujetoService}")
private IEnvioService envioService;
private Envio envio;
private List<Envio> listaAllEnvios;
private LazyEnvioSujetoDataModel lazyListaAllEnvios;
private Envio envioSeleccionado;
/**
*
* Getters y Setters
*/
@PostConstruct
public void init(){
if (lazyListaAllEnvios == null) {
lazyListaAllEnvios = new LazyEnvioSujetoDataModel(envioService);
}
}
public void setEnvioService(final IEnvioService envioService) {
this.envioService = envioService;
}
public Envio getEnvio() {
return envio;
}
public void setEnvio(final Envio envio) {
this.envio = envio;
}
public List<Envio> getListaAllEnvios() {
if (listaAllEnvios == null) {
listaAllEnvios = envioService.getAll();
}
return listaAllEnvios;
}
public void setListaAllEnvios(final List<Envio> listaAllEnvios) {
this.listaAllEnvios = listaAllEnvios;
}
public Envio getEnvioSeleccionado() {
return envioSeleccionado;
}
public void setEnvioSeleccionado(final Envio envioSeleccionado) {
this.envioSeleccionado = envioSeleccionado;
}
/**
* Métodos de navegación
*/
public String goToEditarEnvio() {
FacesUtils.saveObjectInFlashScope("envio", envioSeleccionado);
return "/pages/gestionsujetos/envio.xhtml?faces-redirect=true";
}
public LazyEnvioSujetoDataModel getLazyListaAllEnvios() {
return lazyListaAllEnvios;
}
public void setLazyListaAllEnvios(final LazyEnvioSujetoDataModel lazyListaAllEnvios) {
this.lazyListaAllEnvios = lazyListaAllEnvios;
}
}
另外,我们尝试对数据进行延迟加载,但它不起作用。这是我们使用的数据模型(来自PrimeFaces.org上的Lazy Loading示例的改编类):
package es.cne.sicbios.managedbean.gestionsujetos;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SelectableDataModel;
import org.primefaces.model.SortOrder;
import es.cne.sicbios.entities.tramites.envios.Envio;
import es.cne.sicbios.services.tramites.envios.IEnvioService;
/**
* Dummy implementation of LazyDataModel that uses a list to mimic a real datasource like a database.
*/
@ViewScoped
public class LazyEnvioSujetoDataModel extends LazyDataModel<Envio> implements Serializable, SelectableDataModel<Envio> {
/**
*
*/
private static final long serialVersionUID = 983251078912322527L;
private final List<Envio> datasource;
public List<Envio> getDatasource() {
return datasource;
}
public LazyEnvioSujetoDataModel(final IEnvioService envioService) {
this.datasource = envioService.getAll();
}
@Override
public Envio getRowData(final String rowKey) {
for(final Envio envio : datasource) {
if(envio.getId().equals(rowKey))
return envio;
}
return null;
}
@Override
public Object getRowKey(final Envio envio) {
return envio.getId();
}
@Override
public List<Envio> load(final int first, final int pageSize,
final String sortField, final SortOrder sortOrder, final Map<String,String> filters) {
final List<Envio> data = new ArrayList<Envio>();
//filter
for(final Envio envio : datasource) {
boolean match = true;
for(final Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
final String filterProperty = it.next();
final String filterValue = filters.get(filterProperty);
final String fieldValue = String.valueOf(envio.getClass().getField(filterProperty).get(envio));
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(final Exception e) {
match = false;
}
}
if(match) {
data.add(envio);
}
}
//sort
// if(sortField != null) {
// Collections.sort(data, new LazySorter(sortField, sortOrder));
// }
//rowCount
final int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(final IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else {
return data;
}
}
}
对这个问题有什么想法吗? 提前致谢, Juanjo。
答案 0 :(得分:3)
团队合作的朋友可以得到这个问题的答案。我们正在使用Spring Tool Suite,有时它正在改变JSF托管bean的保存方法。我们需要在web.xml上有这个:
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
答案 1 :(得分:0)
我有同样的问题,在我意识到这是因为我不小心使用
后我修复了它import javax.faces.bean.ViewScoped;
包而不是
import javax.faces.view.ViewScoped;