JSFvalidation错误:值无效

我知道这似乎是一个普通的,但我迷失了它。 单击assessment.jsf中的“添加”按钮时发生。 无论如何,我已经附上了我认为相关的部分。

我调试时没有触发FWIW,AssessmentType.equals()。

提前致谢。

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

assessment.xhtml:

          

assessment.jsf:

 
Presenting Condition Problem Duration

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 { @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 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 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"; } 

编辑:

在调试时注意到这一点,是否可能是可疑的?:

 Daemon Thread [HandshakeCompletedNotify-Thread] (Suspended (exception ConcurrentModificationException)) HashMap$EntryIterator(HashMap$HashIterator).nextEntry() line: 793 HashMap$EntryIterator.next() line: 834 HashMap$EntryIterator.next() line: 832 SSLSocketImpl$NotifyHandshakeThread.run() line: 2214 

validation错误:值无效

到目前为止,此错误表示所选项目与列表中的任何可用项目都不匹配。 即,所选项目值表示的对象在其equals()调用中从未返回true ,并且具有任何可用的选择项。

导致此问题的原因只有两个:

  1. 有问题的对象类型的equals()方法被破坏。
  2. 在表单提交请求的validation阶段,项目列表的内容与在显示表单的初始请求的呈现响应阶段期间的内容不同。

由于第一个似乎是正确实施的 – 按照评论 – ,唯一的原因是第二个。 假设您在getter方法中没有进行业务逻辑,一个简单的测试就是将#{assessmentBean}放在会话范围内。 如果它工作,那么选择项列表的数据(预)加载逻辑肯定是错误的。

validation失败,因为在转换器将AssessmentType的String表示forms转换回对象后,JSF会迭代现有值( assessmentBean.assessment.type.fields )并将此最近转换的对象与所有现有对象进行比较。

由于您没有为AssessmentType实现Object#equals ,因此它将默认为对象标识比较(粗略地说,您的对象的内存地址),这当然会失败。

因此,解决方案是实现Object#equals ,或者让转换器从assessmentBean.assessment.type.fields而不是从AssessmentTypeManager获取对象。

我想我已经解决了这个问题,至少,我已经转向了下一个错误!

尽管发布了大量的代码,我还没有发布完整的xhtml,其中有多个嵌套的表单标签。 只有一个表单似乎允许传递assessmentId参数,而参数允许EvaluBean然后正确填充评估类型的AssessmentFields列表。

谢谢你的帮助。