JSF validation error: value is invalid

I know this seems to be common, but I lost it. Occurs when the "Add" button is clicked in the .jsf rating file. In any case, I have attached what, in my opinion, relates to the relevant sections.

FWIW, AssessmentType.equals () does not start during debugging.

Thanks in advance.

j_idt38:j_idt47:j_idt48: Validation Error: Value is not valid 

assessment.xhtml:

  <h:form> <h:selectOneMenu value="#{assessmentBean.assessmentField}"> <f:selectItems value="#{assessmentBean.assessment.type.fields}" /> </h:selectOneMenu> <h:commandButton value="Add" action="#{assessmentBean.doAddField}"> <f:param name="assessmentId" value="#{assessmentBean.assessment.id}" /> </h:commandButton> </h:form> 

assessment.jsf:

 <form id="j_idt38:j_idt47" name="j_idt38:j_idt47" method="post" action="/jsf-web/edit/assessment.jsf" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="j_idt38:j_idt47" value="j_idt38:j_idt47" /> <select name="j_idt38:j_idt47:j_idt48" size="1"> <option value="1">Presenting Condition</option> <option value="2">Problem Duration</option> </select> <script type="text/javascript" src="/jsf-web/javax.faces.resource/jsf.js.jsf?ln=javax.faces"></script> <input type="submit" name="j_idt38:j_idt47:j_idt50" value="Add" onclick="mojarra.jsfcljs(document.getElementById('j_idt38:j_idt47'),{'j_idt38:j_idt47:j_idt50':'j_idt38:j_idt47:j_idt50','assessmentId':'1'},'');return false" /><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="3431661972220941645:6952134510589038883" autocomplete="off" /> </form> 

AssessmentType.java:

 import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.validation.constraints.NotNull; import lombok.Data; import org.hibernate.envers.Audited; @Audited @Data @Entity public class AssessmentType implements Comparable<AssessmentType> { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NotNull private String name; @OneToMany( fetch=FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, targetEntity=AssessmentField.class ) private List<AssessmentField> fields; @Override public int compareTo(final AssessmentType o) { return getId().compareTo(o.getId()); } @Override public String toString() { return getName(); } } 

AssessmentFieldConverter.java

 import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.FacesConverter; import javax.naming.InitialContext; import javax.naming.NamingException; import com.htu.fizio.api.AssessmentFieldManager; import com.htu.fizio.domain.AssessmentField; @FacesConverter(forClass = AssessmentField.class) public class AssessmentFieldConverter implements Converter { AssessmentFieldManager<AssessmentField> assessmentFieldManager; @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Object getAsObject(FacesContext ctx, UIComponent component, String value) { try { final InitialContext ic = new InitialContext(); assessmentFieldManager = (AssessmentFieldManager) ic.lookup("fizio/AssessmentFieldManagerImpl/local"); return assessmentFieldManager.find(Long.valueOf(value)); } catch (NamingException e) { e.printStackTrace(); } return null; } @Override public String getAsString(FacesContext ctx, UIComponent component, Object value) { return String.valueOf(((AssessmentField) value).getId()); } } 

AssessmentBean.java

  import java.util.List; import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.SessionScoped; import lombok.Getter; import lombok.Setter; import com.htu.fizio.api.AssessmentManager; import com.htu.fizio.domain.Assessment; import com.htu.fizio.domain.AssessmentField; import com.htu.fizio.domain.AssessmentFieldValue; import com.htu.fizio.jsf.faces.FacesUtil; ... @PostConstruct public void init() { if (FacesUtil.containsKey("assessmentId")) { final Long id = Long.parseLong(FacesUtil.get("assessmentId")); assessment = assessmentManager.find(id); } else { assessment = new Assessment(); } } public String doAddField() { final AssessmentFieldValue value = new AssessmentFieldValue(); value.setField(assessmentField); value.setValue(""); assessment.getFieldValues().add(value); assessmentManager.save(assessment); return "/edit/assessment"; } 

Edit:

Just noticed this while debugging, is it probably suspected ?:

 Daemon Thread [HandshakeCompletedNotify-Thread] (Suspended (exception ConcurrentModificationException)) HashMap$EntryIterator(HashMap$HashIterator<E>).nextEntry() line: 793 HashMap$EntryIterator.next() line: 834 HashMap$EntryIterator.next() line: 832 SSLSocketImpl$NotifyHandshakeThread.run() line: 2214 
+4
source share
3 answers

I think I solved it, at least I went on to the next error!

Despite the publication of lines of code, I would not post the full xhtml, which included multiple and nested form tags. It seems that only one form allows you to pass the parameter valuId, which, in turn, allows the appraisal bank to then correctly fill out the list of appraisal fields for the appraisal type.

Thanks for the help.

+2
source

Validation error: value is invalid

As a result, this error means that the selected item does not match any of the items available in the list. That is, the object represented by the selected element value never returned true in its equals() call with any of the available selection elements.

There are two reasons for this problem:

  • The equals() method of the object type in question is aborted.
  • The contents of the list of elements are different during the validation phase of the form submission request than during the response phase of the rendering of the original request to display the form.

Since the first seems to be implemented correctly - as in the comments, the only reason is the second. Assuming you don't run business logic anywhere in the getter method, a simple test is to put #{assessmentBean} in the session area. If this works, the logic for loading data (pre) loading a list of select items is definitely incorrect.

+15
source

The check is not performed because after converting the String representation converter of the AssessmentType object back to the JSF object, iterates over the existing values ​​( assessmentBean.assessment.type.fields ) and compares this newly converted object with all existing ones.

Since you did not implement Object#equals for the AssessmentType parameter, it will by default compare the identifier of the object (roughly speaking, the memory address of your object), which, of course, will fail.

Thus, the solution should either implement Object#equals or allow the converter to get the object from assessmentBean.assessment.type.fields instead of AssessmentTypeManager .

+5
source

All Articles