JSF Validation Error: Value is not valid(值无效)错误解决二

在完成一个功能的时候遇到一个问题:
在使用h:selectOneMenu时即使已经加了<s:convertEntity>仍然报错:value is not valide.

后来google了一下,seam 的论坛上几个帖子分析的原因都是因为实体的equal方法的问题,然后在一篇国内的搏客上看到了一个解决方法:

使用seam时,注意实体的equals方法

作者sulong 分类: java, 程序

当你用jsf的<h:selectOneMenu />之类的控件选择实体时,小心你的实体的equals方法,否则你可能就会遇到”value is not valid”的验证错误。比如,如果你的页面里有这样一段:

<h:selectOneMenu value="#{fooAction.foo}">



<s:selectItems value="#{fooList.resultList}" var="foo" label="#{foo.name}"/>



<s:convertEntity />



</h:selectOneMenu>

你的Foo实体类的equals方法又是这样写的:

public boolean equals(Object obj) {



if (this == obj)



return true;



if (obj == null)



return false;



if (getClass() != obj.getClass())



return false;



final Foo other = (Area) obj;



if (id == null) {



if (other.id != null)



return false;



} else if (!id.equals(other.id))



return false;



return true;



}

很好,你很可能就有机会遭遇seam下这个神奇的value is not valid验证问题了。到底原因何在?原因就在于seam不仅使用了jsf还使用了hibernate,而你的equals方法没有考虑到被对比的双方可能一个是实体类,另一个可能是被hibernate动态增强过的类。JSF在客户端提交表单后,会验证客户端选中的元素是否是当初服务端给他的那些元素。所以,JSF会拿经converter得到的实体与当初的集合里的实体一一调用equals方法对比,如果找不到一个在集合中的实体与提交来的一样,就报错。如果集合里的对象是hibernate 延迟加载时的一个stub,那正常的对象和这个stub对比时就可能出错。对于上面的例子,getClass() != obj.getClass() 会为真,而 other.id != null 也可能为真。怎么办?改写equals方法,如下:

public boolean equals(Object obj) {



if (this == obj)



return true;



if (obj == null)



return false;



if (!getClass().isAssignableFrom(obj.getClass()))



return false;



final Area other = (Area) obj;



if (id == null) {



if (other.getId() != null)



return false;



} else if (!id.equals(other.getId()))



return false;



return true;



}

isAssignableFrom方法对子类调用时一样为真。other.getId()时,则会初始化stub,取出id的值。

还有一种更简单的方法,那就是不要让用户选择实体,而是选择实体的id,那就没这个问题了。

原文地址:http://www.sulong.info/archives/104

我尝试了选择id 的方法,但是总是报错: identifier of an instance of xx was altered from xx to xx.

等过几天再解决一下。

另:如果实体中有需要延迟加载的属性,也可能会报这个错误。

http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4127804

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值