Método de acción JSF no siendo llamado
Tengo una vista JSF con una tabla de datos de Primefaces y un botón de comando en la misma, como sigue:
<p:messages id="statusMessages" showDetail="true" />
<h:form id="listForm">
<p:panel header="Wellsite List">
<br />
<h:outputLabel value="Welcome, #{wellsiteController.loggedUser.login}" />
<br />
<br />
<p:dataTable id="dataTable" var="wellsite" value="#{wellsiteController.wellsiteDataTableModel}"
paginator="true" rows="10" selection="#{wellsiteController.wellsite}">
<p:column selectionMode="single" style="width:18px" id="radioSelect" />
<p:column sortBy="#{wellsite.reference}" headerText="Wellsite ID">
<h:outputText value="#{wellsite.reference}" />
</p:column>
<p:column headerText="Allowed Groups">
<h:outputText value="#{wellsite.allowedGroups.toString()}" />
</p:column>
<f:facet name="footer">
<h:panelGrid columns="3">
<p:commandButton id="addWellsite" value="Add New Wellsite" icon="ui-icon-flag" ajax="false" action="#{wellsiteController.showAddWellsite}"/>
<p:commandButton id="editWellsite" value="Edit Selected Wellsite" icon="ui-icon-wrench" ajax="false" action="#{wellsiteController.showEditWellsite}"/>
<p:commandButton id="deleteWellsiteButton" value="Remove Selected Wellsite" icon="ui-icon-trash" onclick="confirmation.show()" type="button"/>
</h:panelGrid>
</f:facet>
</p:dataTable>
<p:spacer height="20" />
</p:panel>
<p:confirmDialog id="confirmDialog" message="Are you sure you want to remove the selected Wellsite along with all it's data?" header="Confirmation" severity="alert" widgetVar="confirmation">
<p:commandButton id="confirm" value="Yes" ajax="false" oncomplete="confirmation.hide()" action="#{wellsiteController.deleteWellsite}" />
<p:commandButton id="decline" value="Cancel" onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</h:form>
Y aquí está el controlador:
@ManagedBean(name = "wellsiteController")
@RequestScoped
public class WellsiteController implements Serializable {
private static final long serialVersionUID = 1L;
@ManagedProperty("#{wellsiteDao}")
private WellsiteDao wellsiteDao;
@ManagedProperty("#{userDao}")
private UserDao userDao;
@ManagedProperty("#{groupDao}")
private GroupDao groupDao;
@ManagedProperty("#{userController.loggedUser}")
private UserEnt loggedUser;
private WellsiteEnt wellsite;
private List<WellsiteEnt> wellsiteList;
DualListModel<GroupEnt> pickGroupsModel;
public WellsiteController(){
}
@PostConstruct
public void build(){
wellsite = new WellsiteEnt();
wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
}
/*some getters & setters*/
public WellsiteDataTableModel getWellsiteDataTableModel(){
return new WellsiteDataTableModel(getWellsiteList());
}
public void setPickGroupsModel(DualListModel<GroupEnt> model){
pickGroupsModel = model;
}
public DualListModel<GroupEnt> getPickGroupsModel() {
if(pickGroupsModel == null){
List<GroupEnt> allGroups = groupDao.getAll();
List<GroupEnt> currentGroups = wellsite.getAllowedGroups();
for(GroupEnt g : currentGroups){
allGroups.remove(g);
}
pickGroupsModel = new DualListModel<GroupEnt>(allGroups, currentGroups);
}
return pickGroupsModel;
}
public String listWellsites(){
getWellsiteList();
return "listWellsites";
}
public String showAddWellsite(){
FacesContext context = FacesContext.getCurrentInstance();
setWellsite(new WellsiteEnt());
wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
pickGroupsModel = null;
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
"Fields annotated with a ' * ' are mandatory",""));
return "addWellsite";
}
public String addWellsite(){
FacesContext context = FacesContext.getCurrentInstance();
wellsite.setDate(new Date());
wellsite.setLastUpdate(wellsite.getDate());
try {
wellsiteDao.addWell(wellsite);
for(GroupEnt g : pickGroupsModel.getTarget()){
GroupEnt group = groupDao.getOne(g.getGroupId());
group.getGroupWellsites().add(wellsite);
groupDao.update(group);
}
return listWellsites();
} catch (Exception ex) {
Logger.getLogger(WellsiteController.class.getName()).log(Level.SEVERE, null, ex);
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
ex.getMessage(),""));
return null;
}
}
}
Esta vista se renderiza correctamente. El datatable y los botones se ve bien. El problema es que cuando primero hago clic en el botón de comando "addWellsite", no pasa nada. La página parece refrescarse. Si vuelvo a hacer clic, como excepción ocurre:
java.lang.NumberFormatException: For input string: "null"
Usando un depurador, descubrí que la acción "addWellsite" NO se llama la primera vez, y por lo tanto, no se genera ningún resultado (por lo tanto, la actualización de la página).
La excepción probablemente se deba a la falta de inicialización en las vistas actual o de destino (ya que ambas vistas se muestran desde los métodos de acción que no se llamaron en la actualización de la página)
La pregunta es:¿POR QUÉ el método de acción no se llama la primera vez?
A partir deesta respuesta:
Cada vez que unUICommand
el componente no puede invocar la acción asociada, verifique lo siguiente:
UICommand
Los componentes deben colocarse dentro de unaUIForm
componente (por ejemplo,h:form
).Tengo una h: forma
No se puedenido múltipleUIForm
Componentes entre sí (¡cuidado con los archivos incluidos!).Sólo hay uno.
No debería haberse producido ningún error de validación / conversión (usoh:messages
para conseguirlos todos).Tengo un h: mensajes que no muestran ningún error.
SiUICommand
los componentes se colocan dentro de unaUIData
componente, asegúrese de que exactamente el mismoDataModel
(el objeto detrás de laUIData
esvalue
atributo) se conserva.El commandButton está dentro de la tabla de datos, pero la vista de destino no necesita el modelo de datos. Como muestra el código de mi controlador, el objeto se crea a medida que la vista intenta recuperarlo. La siguiente solicitud no está utilizando esta tabla de datos, para que no la maneje más.
losrendered
ydisabled
Los atributos del componente y todos los componentes principales no deben evaluarse parafalse
durante la fase de solicitud de valores de solicitud.No hayrendered
odisbled
atributos
PhaseListener
o cualquierEventListener
en la cadena de solicitud-respuesta ha cambiado el ciclo de vida de JSF para omitir la fase de acción de invocación.No se define PhaseListener.
Asegúrate de que noFilter
oServlet
en la misma cadena de solicitud-respuesta ha bloqueado la solicitud para elFacesServlet
de algun modo.Ningún otro Servlet está definido. Ni siquiera sé qué es un filtro.
¿POR QUÉ el método de acción no se llama la primera vez?