struts2 傳遞json對象時的延遲加載異常處理方法

那麼,爲何會出現這個異常呢?web

究其緣由,居然是Hibernate的懶加載引發的。必定是你傳遞的數據中有引用類型的數據採用了懶加載機制。ajax

好比:我要從Action中向前臺傳送一個Collection<Menuitem>,經過get方法sql

public Collection<Menuitem> getMenuitemList() {
  return this.menuitemList;
 }
json

而其中Menuitem類型的數據結構是:數據結構

public class Menuitem {
 private Long mid;
 private Long pid;//父節點
 private String name;//樹的節點的名稱
 private Boolean isParent;//是否爲父節點
 private String icon;//圖標的路徑
 private Boolean checked;//複選框是否被選中
 /**
  * 菜單權限與用戶是多對多的關係
  */
 private Set<User> users;
dom

//getter(),setter()方法ui

}this

在映射文件Menuitem.hbm.xml中users屬性的配置以下:spa

<set name="users" table="user_menuitem" inverse="true">
         <key column="mid"></key>
         <many-to-many column="uid" class="cn.myoa.domain.User"></many-to-many>
</set>
插件

未設置lazy="false",則默認採用懶加載模式。

當中間表user_menuitem中沒有數據時,ok,不會牽涉到use表,也就不存在懶加載問題,運行一切正常。

可是當user_menuitem表中有數據,且數據與所傳送的Menuitem對象有關時,就會有問題了

由於懶加載,這樣在Action中獲取的Menuitem對象中的users屬性中的set集合中會存在user對象的引用,可是user的信息其實並未加載,

只有當用到時,容器纔再次發出sql請求進行加載,可是在json插件對menuitemList進行處理以轉換成json格式時,Hibernate Session早已關閉,這樣user信息便加載不成功,而它又沒法對set集合中空的引用進行處理,因此便拋出了JSONException。

有人可能會有疑問,我在web.xml中配置了OpenSessionInViewFilter過濾器,爲何Session還會關閉呢!?

這個疑問問的好!!我也不知何故,在網上也沒找到相關的解釋,不知是否是ajax的XMLHttpRequest的問題,

總之,在struts2與ajax結合的過程當中,OpenSessionInView模式不起做用了!請知道的朋友不吝賜教!

 

好!既然知道了問題的緣由,那麼解決方法就很明瞭了!

方法一:設置lazy="false",即對user不採用懶加載。如

         <set name="users" table="user_menuitem" inverse="true"lazy="false">
         <key column="mid"></key>
         <many-to-many column="uid" class="cn.myoa.domain.User"></many-to-many>
         </set>

          不過這時要注意在User對象中有沒有其餘對象的引用,用過有,也要設置爲非懶加載模式。

方法二:忽略set<User> users 屬性,(推薦使用)

          若是在前臺頁面不須要使用該屬性的話,就不要把他傳到前臺去,設置方法是在其getter方法上加一註解: @JSON(serialize=false)

          @JSON(serialize=false)
          public Set<User> getUsers() {
                  return users;
          }

         這樣json插件在轉換數據時就會忽略該屬性。

如今問題應該已經解決了!!

下面關於struts2和ajax的結合還有幾點建議:

一、在頁面用不到的數據最好不要傳到前臺(這也是之因此推薦第二種方法的緣由,傳的數據越大,效率越低不是嗎!)

二、不是向前臺傳數據的方法最好不要以get開頭,json插件會把全部get開頭的方法當作屬性,轉爲json格式數據

三、若是方法必須以get開頭,然而又不是爲了轉爲json格式,那麼能夠在該方法上加註解:@JSON(serialize=false)

四、須要傳到前臺的數據,必定要在dao中加載完畢,不能使用懶加載模式。

相關文章
相關標籤/搜索