0

I've been using JSF for a couple of months. My bean Person has a lot of fields (about 50) and some sub-beans (4 Addresses, 2 Contacts..): the related form is big and managed with some ajax actions. I would use that form for "new" Person and also for "edit" Person.

Following Creating master-detail pages for entities, how to link them and which bean scope to choose now I have a form for person.xhtml, a search page search_p.xhtml where I choose Person and go to edit_person.xhtml.

search_p.xhtml has a list of Person, each person has this link

<h:link value="Open" outcome="person">
 <f:param name="id_p" value="#{person.id}"/>
</h:link>

person.xhtml contains

<f:metadata>
 <f:viewParam name="id_p" value="#{editPerson.person}"
 converter="#{personConverter}"
 converterMessage="Person unknown, please use a link from within the system."
 required="true" requiredMessage="Bad request, please use a link from within the system." />
</f:metadata>

PersonConverter has

@ManagedBean
@RequestScoped
public class PersonConverter implements Converter {
 public Object getAsObject(FacesContext context, UIComponent component, String value) {
  if (value == null || value.isEmpty()) return null; 
  try {
   if(value.equals("new")) return new Person(); //used for link to new
   else {
    Integer id = Integer.valueOf(value);
    return PersonDAO.getById(id.intValue());
   }
  } catch (NumberFormatException e) { throw new ConverterException("Not valid Person ID: " + value, e); }
 }

 @Override    
 public String getAsString(FacesContext context, UIComponent component, Object value) {        
  if (value == null) return "";
  if (value instanceof Ordine) {
   Integer id = ((Ordine) value).getId();
   return (id != null) ? String.valueOf(id.intValue()) : null;
  } else {
   throw new ConverterException("Not valid Person ID: " + value);}
 }
 }

side_menu.xhtml is part of template, here it calls "New Person"

<li><h:link value="New" outcome="person">
  <f:param name="id_p" value="new" />
</h:link></li>

EditPerson bean is

@ManagedBean
@ViewScoped
public class EditPerson implements Serializable {
    private static final long serialVersionUID = 1768587713177545840L;
    private Person person; 

    public Person getPerson() {return person;}
    public void setPerson(Person person) {this.person = person;}
    public String save() {
        PersonDAO.addOrUpdate(person);
        return "/search_p?faces-redirect=true";
    }

So, when in person.xhtml I click on

Contact 2
<h:selectBooleanCheckbox value="#{editPerson.person.enable_c2}" id="flag_c2">
    <f:ajax event="click" execute="flag_c2" render="div_c2"></f:ajax>
</h:selectBooleanCheckbox>

a popup appears: serverError: class javax.faces.component.UpdateModelException /include/person/tab_anag.xhtml @372,26 value="#{editPerson.person.enable_f2}": Target Unreachable, 'person' returned null. PersonConverter has been fired, i suppose because of f:metadata is in the page code: can i avoid to call PersonConverter when ajax is fired? I need f:metadata only for passing id from search_p page.

Skizzo
  • 1
  • 2
  • 1
    Editing a new entry is the same as editing an existing empty entity, so using one page (with maybe some fields read-only when updating) is the way to go. – Kukeltje Feb 05 '19 at 17:01
  • This is effectively a fully new question. – Kukeltje Feb 07 '19 at 18:25
  • And your last statement is not correct, you only need the viewparam om page loading and not ajax. Search for that has been asked before – Kukeltje Feb 07 '19 at 18:27
  • @Kukeltje thanks for comments. I solved using Omnifaces, so with required="#{not facesContext.postback}". In this way every ajax call uses the same object Person instead of creating new one. – Skizzo Feb 13 '19 at 11:07

0 Answers0