I have a pretty typical CRUD situation that I am struggling with, so I believe that I should misunderstand something. I put together a small demo application to better explain my problem. Below are two files of interest:
PersonView - Managed CDI Bean supporting JSF page
package example import java.io.Serializable; import java.util.List; import javax.enterprise.context.Conversation; import javax.enterprise.context.ConversationScoped; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; @ConversationScoped @Named public class PersonView implements Serializable { private Person selectedPerson; @Inject private PersonService personService; @Inject private Conversation conversation; public PersonView() {} public List<Person> getPeople() { return personService.findAll(); } public void beginConversation() { if( conversation.isTransient() ) {conversation.begin();} } public void endConversation() { if( !conversation.isTransient() ) { conversation.end();} } public void createPerson() { beginConversation(); setSelectedPerson( new Person() ); } public void addPerson() { personService.addPerson( getSelectedPerson() ); endConversation(); } public void updatePerson() { personService.updatePerson( getSelectedPerson() ); } public Person getSelectedPerson() { return selectedPerson; } public void setSelectedPerson(Person selectedPerson) { this.selectedPerson = selectedPerson; } }
index.xhtml - JSF page for managing people
<?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"> <html 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"> <h:head> <title>CRUD Example</title> </h:head> <h:body> <h:form prependId="false"> <p:dataTable var="p" value="#{personView.people}" id="person_table" rowKey="#{p.id}" selection="#{personView.selectedPerson}"> <p:column selectionMode="single"/> <p:column><f:facet name="header">ID</f:facet>#{p.id}<p:column> <p:column><f:facet name="header">Name</f:facet>#{p.name}</p:column> <f:facet name="footer"> <p:commandButton value="Create Person" onclick="create_dialog.show();" actionListener="#{personView.createPerson}"/> <p:commandButton value="Edit Person" onclick="edit_dialog.show();" update="edit_panel"/> </f:facet> </p:dataTable> </h:form> <p:dialog header="Create Person" id="create_dialog" widgetVar="create_dialog" modal="true" width="750" height="300"> <h:form prependId="false"> <p:panel id="create_panel"> <p>Name: <p:inputText value="#{personView.selectedPerson.name}" required="true"/></p> <p><p:commandButton value="Add" actionListener="#{personView.addPerson}" oncomplete="create_dialog.hide();" update="person_table" /></p> </p:panel> </h:form> </p:dialog> </h:body>
The index page shows the user a data table containing all the people the system knows about. Then click the "Create Person" button at the bottom of the table. I checked that this correctly calls the createPerson method, and the conversation seems to be starting. Then create_dialog is displayed, where the user can enter a name. The problem occurs when the user clicks the Add button. JSF tries to save the username, but the selectedPerson variable is now null, so it does not work with a NullPointerException.
I understand that this is not the usual way to create objects, but it makes sense in my current application, as I can guess some of the values ββof the new Person. It is also great for the way I would like to edit.
So my question (s): why is the conversation not spreading? PersonView Bean is always in the request area. I read about @ViewScoped in JSF2, but I would rather stick with CDI if possible. From what I read, I think the problem is the inability to pass the CID name with the request, but I donβt understand how to do this with AJAX.
The only solution I came up with is to bring the PersonView into the session, but it looks like a huge kludge. e
source share