2012-11-01 40 views
1

我在這裏有一個問題,似乎對我有好處。如果有人能幫助我,我會很感激!託管沒有更新第二次提交的最新信息<updated>

上下文:
我有一個p:對話框(primefaces),顯示JPA實體的詳細信息。在此對話框中,用戶可以修改信息並提交。一旦提交,信息就會保存在數據庫中(通過JPA)。

p:對話框被「包裝」在組件中以供在不同情況下使用。

問題:
如果我表現出與數據庫中選擇一個實體對話框,修改了一些信息,然後點擊保存(提交)按鈕:正常工作的第一次。數據庫被更新並且p:對話框被隱藏。
如果我再次顯示具有相同實體的對話框,請再次修改p:對話框中的數據並再次提交:似乎一切正常(確認消息&日誌),但數據庫爲而不是已更新。

在任何時候,在p:對話框中找到的信息都是正確的。在BackingBean & DB中找到的數據雖然在第一次提交後纔是最新的。

另一個線索:如果在提交操作後,我刷新頁面,它將工作多一個提交。

調試信息:
據發貼者提交的信息(長壽命螢火蟲!!!)發佈的所有數據都是正確的(始終是最新的)。但是,如果我在日誌中顯示支持bean接收的內容,它與之前的提交內容相同(而不是新的信息)。

該數據發佈正確,但似乎很糟糕的接收/解釋。這就好像問題發生在接收提交的帖子時,發生在JSF生命週期的RestoreView,ApplyRequestValue,ProcessValidation或UpdateModelValue階段之一中。

所以,第二次保存(提交)似乎工作,但不是因爲保存在數據庫中的數據是相同的每個後續提交..... 爲什麼?

我用Glassfish的3.1.2,鑽嘴魚科2.1.13,JSF,PrimeFaces,CDI,JPA,休眠...

代碼Snipets:
頁面包含p:對話框(CMPNT:dataEntryDialog )的組件:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:p="http://primefaces.org/ui" 
     xmlns:cmpnt="http://java.sun.com/jsf/composite/component" 
> 
    <h:head> 
     <title> 
      Test!!! 
     </title> 
    </h:head> 
    <h:body> 
     <h:commandButton type="button" onclick="PVDlg.show();" value="show dlg"/> 
     <cmpnt:dataEntryDialog id="PVDataEntry" video="#{processStatus.testedVideo}" fieldGroupId="2" 
       header="This is a test" 
       widgetVar="PVDlg" render="@this"/> 
    </h:body> 
</html> 

號碼:對話框的組件實現(CMPNT:dataEntryDialog):

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:composite="http://java.sun.com/jsf/composite" 
     xmlns:c="http://java.sun.com/jsp/jstl/core" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:p="http://primefaces.org/ui"> 

    <composite:interface componentType="dataEntryComponent"> 
     <composite:attribute name="video" required="true"/> 
     <composite:attribute name="widgetVar" required="true"/> 
     <composite:attribute name="render" required="false"/> 
     <composite:attribute name="closeActionListener" method-signature="void listener(org.primefaces.event.CloseEvent)" required="false" /> 
     [... other attributes] 
    </composite:interface> 

    <composite:implementation> 
     <h:outputStylesheet library="css" name="dataEntryDialog.css" target="head" /> 

     <div id="#{cc.clientId}"> 
      <script type="text/javascript"> 
       function handleDataEntrySaveAttempt(xhr, status, args) { 
        if(args.validationFailed || !args.saved) { 
         jQuery('#' + #{cc.clientId} + ':cmpntDataEntryDialog').effect("shake", {times:3}, 100); 
        } else { 
         ${cc.attrs.widgetVar}.hide(); 
        } 
        return true; 
       } 
      </script> 
      <p:dialog 
        id="cmpntDataEntryDialog" 
        header="#{cc.attrs.header}" 
        widgetVar="#{cc.attrs.widgetVar}" 
        resizable="false" 
        showEffect="fade" 
        hideEffect="fade" 
        dynamic="true" 
        minimizable="true" 
        maximizable="false" 
        width="550" 
        height="500" 
      > 
       <h:form id="cmpntDataEntryForm" style="position:relative;"> 
        <div style="height:460px;"> 
         <div style="width:100%;height:100%;margin-bottom:5px;overflow:auto;"> 
          <ui:repeat value="#{dataEntryDialog.loadDataEntryFields(cc.attrs.video, cc.attrs.fieldGroupId)}" var="field" varStatus="fieldRankInfo"> 
           <div style="position:relative;width:100%;height:24px;margin:4px 0px;"> 
            <h:outputText value="#{field.fieldName}:" style="vertical-align:middle;" styleClass="margin"/> 
            <p:calendar id="cmpntInputDate" value="#{field.value}" rendered="#{'java.util.Date' eq field.type}" styleClass="input margin" effect="drop" /> 

            <p:selectOneMenu id="cmpntInputComboBox" value="#{field.value}" rendered="#{'ComboBox' eq field.type}" styleClass="input margin"> 
             <f:selectItem itemLabel="SelectAValue"/> 
             <f:selectItems value="#{field.possibleValues}"/> 
             <f:converter converterId="com.ctec.world.ConvertInteger" /> 
            </p:selectOneMenu> 

            [... some other optionally rendered fields for different data types] 

           </div> 
          </ui:repeat> 
         </div> 
        </div> 
        <div style="position:relative;bottom:0;"> 
         <div style="float:right;margin-top:5px;"> 
          <p:commandButton id="cmpntSubmit" action="#{dataEntryDialog.save(cc.attrs.video.video)}" 
            value="${cc.resourceBundleMap.dataEntryDialog_Save}" 
            process="@form" update="${cc.attrs.render} @form" 
            styleClass="margin" oncomplete="handleDataEntrySaveAttempt(xhr, status, args)"/> 
          <p:commandButton id="cmpntCancel" 
            value="${cc.resourceBundleMap.dataEntryDialog_Cancel}" 
            onclick="${cc.attrs.widgetVar}.hide();" styleClass="margin"/> 
         </div> 
        </div> 
       </h:form> 
      </p:dialog> 
     </div> 
    </composite:implementation> 
</html> 

關於Managed beans,它們是普通的CDI @Named @SessionScoped bean。

附加信息:
我做了進一步測試:通過階段聽衆去看看是否有從那裏有有趣的信息......這裏沒有運氣直到現在訪問的任何對象。

但更有趣的是,我簡化了案例,並從這篇文章中刪除了無關的信息。

+0

我不知道問題是什麼。但是,經常幫助我追蹤使用Primefaces構建的組件中的錯誤,並在我的''中添加了'ajax =「false」'。默認情況下,您可能知道Primefaces''帶有AJAX的帖子。奇怪的是,有幾次禁用AJAX給了我JSF的有用錯誤信息,而在啓用AJAX的情況下,我會得到*沒有任何事情發生*行爲。試試看看它是否有助於追蹤問題,然後在您修復問題時恢復原狀。 – rdcrng

+0

嘗試了您的建議,但不會更改任何內容(我的意思是沒有其他有用的錯誤消息)。我無法證明問題是什麼,但它似乎與我用來避免javax.persistence.OptimisticLockException的方式有關。 ...很快就會有更多細節! – ChaudPain

回答

0

我懂了!問題不在於表示層(多麼令人驚訝!)。這與我的邏輯有關。不久前,我通過使用實體管理器的合併方法返回的託管實例更改實體實例(不再由entityManager管理)來修復JPA樂觀鎖定異常。我的設計並沒有像預期的那樣支持這種變化......我受到了帖子內容的吸引,這是正確的,但我沒有去實體實例,我期待它。我想更多的網頁開發經驗不會受到傷害!

相關問題