Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
          在完成一個功能的時候遇到一個問題:
          在使用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



          posted on 2009-03-12 16:49 seal 閱讀(853) 評論(0)  編輯  收藏 所屬分類: Seam
          主站蜘蛛池模板: 当涂县| 历史| 高淳县| 桂平市| 恩施市| 北宁市| 敖汉旗| 宁南县| 溧水县| 始兴县| 阿拉善左旗| 洛阳市| 南投县| 信丰县| 正宁县| 五寨县| 嵊州市| 景德镇市| 内江市| 来宾市| 萨嘎县| 拉萨市| 庆城县| 邵武市| 肇源县| 邹城市| 沂南县| 大港区| 冕宁县| 微山县| 罗源县| 稷山县| 本溪市| 南昌县| 雅安市| 博客| 莱西市| 随州市| 北流市| 定结县| 建水县|