JSF ValueChangeEvent bei Submit eines Formulars

Dieses Thema JSF - ValueChangeEvent bei Submit eines Formulars im Forum "Web Tier" wurde erstellt von Marku, 6. Aug. 2016.

Thema: ValueChangeEvent bei Submit eines Formulars Hallo, in einem Form gibt es eine ComboBox. Wenn das Form sofort abgesendet wird, funktioniert alles wie erwartet....

  1. Hallo,
    in einem Form gibt es eine ComboBox. Wenn das Form sofort abgesendet wird, funktioniert alles wie erwartet. Wird jedoch vorher ein anderer Wert in der ComboBox ausgewählt und dann erst submitted, dann wird ständig ein ValueChangeEvent ausgelöst. Eigentlich sollte ein ValueChangeEvent nur bei einer Änderung des Wertes in der ComboBox gefeuert werden, nicht jedoch bei einem Absenden des Forms. Zuerst dachte ich, die equals-Methode der ProjectEntity ist falsch doch das scheint nicht der Fall zu sein. Sie wurde auch von der IDE erzeugt. Ersetzt man ProjectEntity durch einen String, dann klappt es. Ich finde einfach den Fehler nicht.
    Im Anhang das vollständige Beispiel als Maven-Modul. Bauen mit "mvn clean install". Das ear-File kann direkt z.B. auf einem Wildfly deployed werden.
    Ähm, habe übrigens gesucht, wie man seine Beiträge optimal formatieren kann, aber bis auf diesen Editor nichts gefunden. Ich kenne nur das Code-Element. Wo finde ich mehr?

    Code (Text):

       <?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://xmlns.jcp.org/jsf/html"
          xmlns:f="http://xmlns.jcp.org/jsf/core">
       <h:body>
         <h:form>
           <h:panelGrid columns="3">
             <h:outputLabel value="Projekt"
                    for="projectSelector"/>
             <h:selectOneMenu id="projectSelector"
                      value="#{timeBean.model.projectSelected}"
                      converter="projectConverter"
                      onchange="submit()"
                      valueChangeListener="#{timeBean.projectChanged}"
                      immediate="true"
                      required="true">
               <f:selectItems value="#{timeBean.model.allProjects}"
                      var="singleProject"
                      itemValue="#{singleProject}"
                      itemLabel="#{singleProject.name}"/>
             </h:selectOneMenu>
             <h:message for="projectSelector"/>
           </h:panelGrid>

           <h:panelGrid columns="1">
             <h:commandButton value="Absenden"
                      action="#{timeBean.myAction}"
                      ajax="false"/>

             <h:outputLabel value="#{timeBean.model.resultValue}" rendered="#{not empty timeBean.model.resultValue}"/>
           </h:panelGrid>
         </h:form>
       </h:body>
       </html>
     
    Code (Text):

       public class ProjectEntity {

         private Long id;

         private String name;

         public Long getId() {
           return id;
         }

         public void setId(Long id) {
           this.id = id;
         }

         public String getName() {
           return name;
         }

         public void setName(String name) {
           this.name = name;
         }

         @Override
         public boolean equals(final Object o) {
           if (this == o)
             return true;
           if (o == null || getClass() != o.getClass())
             return false;

           final ProjectEntity that = (ProjectEntity) o;
           System.out.println("equals comparing this " + this.getId() + " to that " + that.getId());

           return id != null ? id.equals(that.id) : that.id == null;
         }

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

         @Override
         public String toString() {
           return "ProjectEntity{" + "id=" + id + ", name='" + name + "'}";
         }
       }
     
    Code (Text):

       public class TimeModel {

         private ProjectEntity projectSelected;

         private List<ProjectEntity> allProjects;

         private String resultValue = "presetValue";

         ... getters und setters ...
       }
     
    Code (Text):

       @Named
       @ViewScoped
       public class TimeBean implements Serializable {

         @Inject
         private ValueProvider valueProvider;

         @Inject
         private Logger log;

         private TimeModel model;

         @PostConstruct
         public void init() {
           model = new TimeModel();
           final List<ProjectEntity> allProjects = valueProvider.getAllProjects();
           model.setAllProjects(allProjects);
           model.setProjectSelected(allProjects.get(0));
         }

         public String myAction() {
           log.info("myAction called");
           model.setResultValue("action was called");
           return null;
         }

         public void projectChanged(final ValueChangeEvent event) {
           final ProjectEntity projectSelected = (ProjectEntity) event.getNewValue();
           log.info("value changed from " + model.getProjectSelected().getId() + " to " + projectSelected.getId());
           model.setProjectSelected(projectSelected);
           final FacesContext context = FacesContext.getCurrentInstance();
           context.renderResponse();
         }

         public TimeModel getModel() {
           return model;
         }

         public void setModel(TimeModel model) {
           this.model = model;
         }
       }
     
    Code (Text):

       @FacesConverter(value = "projectConverter")
       public class ProjectConverter implements Converter {

         @Inject
         private ValueProvider valueProvider;

         @Override
         public Object getAsObject(final FacesContext facesContext, final UIComponent uiComponent, final String projectName) throws ConverterException {
           if (StringUtils.isEmpty(projectName)) {
             return null;
           }
           final List<ProjectEntity> projects =  valueProvider.getAllProjects();
           for (ProjectEntity project : projects) {
             if (StringUtils.equals(projectName, project.getName())) {
               return project;
             }
           }
           throw new ConverterException("1");
         }

         @Override
         public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object value) throws ConverterException {
           if (value == null) {
             return null;
           }
           if (value instanceof ProjectEntity) {
             return ((ProjectEntity) value).getName();
           }
           throw new ConverterException("2");
         }
       }
     
     

    Anhänge:

  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Wäre um jeden Tip dankbar. Ich komme damit einfach nicht weiter. Habe extra eine lauffertige App erstellt. In der Logausgabe sieht man, dass equals eigentlich korrekt sein müsste.