2012-07-27 16 views
0

我確實有一個問題,我不知道它發生了什麼...... GWT初學者,在一個個人項目上工作。GWT RequestFactory STRANGE行爲:沒有錯誤報告

環境:

  • 行家項目與兩個模塊

    • 一個模塊是 '模型',並具有休眠HSQLDB春天依賴關係。 HSQLDB運行嵌入,在存儲器中,從彈簧的applicationContext.xml

    • 另一個模塊是 '網絡' 和配置有所有GWT依賴性

該應用程序是使用內置一些Spring Roo生成代碼作爲基礎,稍後進行修改和擴展。

問題是,當編輯一些實體字段並按保存時,什麼也沒有發生。創建新實體實例時沒有問題,僅在編輯時更改某個字段並按'保存'基本上覆蓋了新值。 所以我開始徹底調試客戶端代碼,啓用了hibernate和Spring詳細日誌記錄,但仍然...什麼都沒有。

然後,我做了一個令人驚訝的(對我來說)發現。 檢查GWT的響應有效載荷,我已經看到了這一點:

{"S":[false],"O":  [{"T":"663_uruC_g7F5h5IXBGvTP3BBKM=","V":"MS4w","S":"IjMi","O":"UPDATE"}],"I":[{"F":true,"M":"Server Error: org.hibernate.PersistentObjectException: detached entity passed to persist: com.myvdm.server.domain.Document; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.myvdm.server.domain.Document"}]} 

啊哈,通過分離的實體堅持! 請注意,gwt客戶端代碼使用此代碼段來調用服務:

requestContext.persist()。using(proxy);

可以說這可能會引發異常,並調用合併()可以解決這個問題,但是,閱讀,3題......現在

三個問題就出來了:

  • 爲什麼這不是以某種方式作爲錯誤/異常發送給客戶嗎?
  • 爲什麼Hibernate沒有這樣記錄?
  • 爲什麼Spring Roo生成代碼(正如我所說的,用作基礎)的工作原理沒有解決這個問題?

非常感謝,

Avaiting一些意見/建議。


編輯完成後T. BROYER的迴應::

喜托馬斯,感謝您的答覆。

我有一個實現RequestTransport並實現send()的自定義類。這就是我收集響應負載的方式。實施如下::

public void send(String payload, final TransportReceiver receiver) { 
    TransportReceiver myReceiver = new TransportReceiver() { 

     @Override 
     public void onTransportSuccess(String payload) { 
      try { 
       receiver.onTransportSuccess(payload); 
      } finally { 
       eventBus.fireEvent(new RequestEvent(RequestEvent.State.RECEIVED)); 
      } 
     } 

     @Override 
     public void onTransportFailure(ServerFailure failure) { 
      try { 
       receiver.onTransportFailure(failure); 
      } finally { 
       eventBus.fireEvent(new RequestEvent(RequestEvent.State.RECEIVED)); 
      } 
     } 
    }; 

    try { 
     wrapped.send(payload, myReceiver); 
    } finally { 
     eventBus.fireEvent(new RequestEvent(RequestEvent.State.SENT)); 
    } 
} 

這裏是當「保存」按鈕被點擊在編輯模式時執行的代碼:

RequestContext requestContext = editorDriver.flush(); 
    if (editorDriver.hasErrors()) { 
     return; 
    } 

    requestContext.fire(new Receiver<Void>() { 
     @Override 
     public void onFailure(ServerFailure error) { 
      if (editorDriver != null) { 
       setWaiting(false); 
       super.onFailure(error); 
      } 
     } 

     @Override 
     public void onSuccess(Void ignore) { 
      if (editorDriver != null) { 
       editorDriver = null; 
       exit(true); 
      } 
     } 

     @Override 
     public void onConstraintViolation(Set<ConstraintViolation<?>> errors) { 
      if (editorDriver != null) { 
       setWaiting(false); 
       editorDriver.setConstraintViolations(errors); 
      } 
     } 
    }); 

根據你說的話,的onSuccess()應該被調用,它被稱爲

那麼我如何精確地隔離產生問題的代碼呢?我有這樣的方法,爲了創建一個新的請求上下文來持久化對象

 @Override 
     protected RequestContext createSaveRequestContextFor(DocumentProxy proxy) { 
      DocumentRequestContext request = requests.documentRequestContext(); 
      request.persist().using(proxy); 
      return request; 
     } 

,這是它怎麼叫::

editorDriver.edit(getProxy(), createSaveRequestContextFor(getProxy())); 

至於春節的問題,你是說,在兩個後續請求中,find()和persist()之間,JPA entityManager不應該關閉。我仍然在研究這一點,但是當我按下編輯按鈕後,我看到消息'org.springframework.orm.jpa.EntityManagerFactoryUtils - 關閉JPA EntityManager',那是不對的,也許@Transactional註釋沒有被應用...

回答

2

爲什麼不以某種方式作爲錯誤/異常發送給客戶端?

它是。 "S": [false]表示第一個(也是唯一的)方法調用(請記住,RequestContext是一批!)失敗。將調用調用ReceiveronFailure方法。

ServerFailure"F": true然後說,這是一個致命錯誤,所以Receiver#onFailure默認實現將拋出一個RuntimeException。但是,因爲根本沒有使用Receiver,所以沒有任何反應,並且錯誤被忽略。

請注意,批量請求本身已成功,因此全局Receiver(您將傳遞給RequestContext#fire的那個)將調用其方法onSuccess
另請注意,Request#fire(Receiver)Request#to(Receiver)後面跟RequestContext#fire()(沒有參數)的簡寫。

爲什麼Hibernate沒有這樣記錄?

這我不知道,對不起。

爲什麼Spring Roo生成的代碼(正如我所說的,用作基礎)工作時沒有顯示這個問題?

OK,讓我們探索異常的根本原因:該實體由您Locator(或實體類的findXxx靜態方法)加載,然後persist方法被調用的實例。如果您在findpersist方法中未使用相同的JPA EntityManager /休眠會話,則會遇到問題。
請求工廠希望您使用打開會話的視圖模式來克服這一點。不幸的是,我不知道Spring Roo生成了什麼樣的代碼。

1

關於托馬斯提到的觀點模式公開會議,只是添加此過濾器定義你的web.xml在Spring應用程序開啓模式:

<filter> 
    <filter-name> 
     Spring OpenEntityManagerInViewFilter 
    </filter-name> 
    <filter-class> 
     org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 
    </filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

好,謝謝烏米特,我發現這個問題,這是由於一些格式不正確的配置文件造成的......但是,有一個問題仍然存在,爲什麼Hibernate沒有報告任何錯誤?在這樣的事情上,我肯定會看到堆棧跟蹤... – 2012-07-31 05:34:15

+1

我不記得100%,但我有一個類似的設置Hibernate + JPA2 + Requestfactory,當我遇到這個問題,我相信有一個異常拋出保存方法,我得到它在GWT的控制檯登錄。不知道我的Spring應用程序是否也記錄了它。 – 2012-07-31 06:59:01