2011-05-05 57 views
1

我要去嘗試儘可能完整,不久,我可以解釋我的問題...Spring MVC中 - 後丟失兒童實體提交

Web應用程序,在Spring MVC的2.5 +休眠+ Java 6中(由不使用註釋!)。

我有一個控制器擴展SimpleFormController和一個jsp頁面,它的formView和successView。

此控制器應該幫助我插入一個實體PracticeT,它已連接(多對一)查找實體PracticeConfT(將其視爲「類型學」)。我需要通過下拉菜單選擇「類型學」。在我的Web應用程序中,我需要能夠保存插入的數據,並在需要時提交批准請求。

該頁面有一些文本字段和該下拉菜單。被稱爲默認「命令」的bean是NewPracticeBean,它在一個對象PracticeT的引用內。

問題是:我填寫表單,從下拉菜單中選擇一種類型,我提交表單並將數據保存在數據庫中,但當我回到視圖時,每個屬性都存在,但下拉列表菜單不是:它具有允許的所有選項,但沒有選擇任何選項。一些檢查顯示實體PracticeConfT爲null(但它已正確記錄在db上,並且在模型中調試它仍然存在,直到方法onSubmit !!!的最後)。

我希望有人能幫助我。先謝謝你! 再見, Dolfiz

這裏是一些有用的代碼: (我不認爲冬眠的配置可能是問題,但如果你需要的話,我可以將它張貼太)

newPractice.jsp

<form:form id="newPracticeForm" commandName="command"> 
    <input type="hidden" name="action"/> 
    <spring:nestedPath path="practiceT"> 
     <table class="table-data-form"> 
      <tr> 
       <td class="left"><spring:message code="" text="Practice type" /></td> 
       <td> 
        <form:select path="practiceConfT" multiple="false"> 
         <form:option value="" label="- seleziona -"/> 
         <form:options items="${practiceTypeList}" itemValue="idPracticeConf" itemLabel="practiceName"/> 
        </form:select> 
       </td> 
      </tr> 
      <tr> 
       <td class="left"> 
        <spring:message code="" text="Opzione divisa" /> 
        <br/><form:errors cssClass="errors" path="opzioneDivisa" /> 
       </td> 
       <td><form:input path="opzioneDivisa" /></td> 
      </tr> 
      <tr> 
       <td colspan="1"> 
        <input type="submit" name="submit" id="submit" value="Save" class="buttonEMS" style="width:100px;" /> 
       </td> 
      </tr> 
     </table> 
    </spring:nestedPath> 
</form:form> 

NewPracticeBean.java

public class NewPracticeBean implements Serializable{ 

    private PracticeT practiceT; 
    private String action; 
    private boolean typeSelected; 

    public NewPracticeBean(){ 
     super(); 
     this.practiceT = new PracticeT(); 
    } 

    // getters & setters... 
} 

PracticeT.java

public class PracticeT implements java.io.Serializable { 

    private long idPractice; 
    private PracticeConfT practiceConfT; 
    private String opzioneDivisa; 

    // getters & setters... 
} 

PracticeConfT.java

public class PracticeConfT implements java.io.Serializable { 

    public static final String PRACTICE_NAME = "practiceName"; 

    private long idPracticeConf; 
    private String practiceName; 

    // getters & setters... 
} 

NewPracticeController.java 公共類NewPracticeController延伸SimpleFormController {

protected SmartLogger log = SmartLogger.getLogger(this.getClass()); 

    private PracticeSu practiceSu; 
    private ConfigurationSu configurationSu; 

    private HibernateEntityDataBinder practiceConfTBinder; 
    private HibernateEntityDataBinder practiceTBinder; 

    public NewPracticeController() { 
     setCommandClass(NewPracticeBean.class); 
     setCommandName("command"); 
    } 

    @Override 
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { 
     log.trace("NewPracticeController -- initBinder"); 
     super.initBinder(request, binder); 
     binder.registerCustomEditor(PracticeT.class, "practiceT", practiceTBinder); 
     binder.registerCustomEditor(PracticeConfT.class, "practiceT.practiceConfT", practiceConfTBinder); 
    } 

    @Override 
    protected Map referenceData(HttpServletRequest request) throws Exception { 
     log.trace("NewPracticeController -- referenceData"); 
     Map model = new HashMap(); 
     RetrieveAllEntitiesReq req = new RetrieveAllEntitiesReq(); 
     req.setEntity(PracticeConfT.class); 
     req.setOrderProperty(PracticeConfT.PRACTICE_NAME); 
     RetrieveAllEntitiesResp resp = configurationSu.retrieveAllEntities(req); 
     List entitiesList = resp.getEntitiesList(); 
     model.put("practiceTypeList", entitiesList); 

     return model; 
    } 

    @Override 
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { 
     NewPracticeBean practiceBean = (NewPracticeBean)command; 
     Map model = errors.getModel(); 

     CreateNewPracticeReq req = new CreateNewPracticeReq(); 
     req.setPracticeT(practiceBean.getPracticeT()); 
     CreateNewPracticeResp resp = practiceSu.createNewPractice(req); 
     practiceBean.setPracticeT(resp.getPracticeT()); 

     model.putAll(referenceData(null)); 
     model.put(getCommandName(), practiceBean); 

     return new ModelAndView(getSuccessView(), model); 
    } 

    // setters and getters... 
} 
+0

我想強調的是: - 在JSP頁面中PracticeConfT爲空 - 同樣PracticeConfT不返回語句前的onSubmit方法中的null – Dolfiz 2011-05-05 08:46:27

+1

嘗試向PracticeConfT添加一個Equals方法,因爲我想它是等於但不相同! – Ralph 2011-05-05 09:17:18

+0

我應該使用fromBackingObject方法檢索PracticeConfT並在呈現表單之前將其設置在PracticeT中?看起來很奇怪...我猜想綁定是自動的...我敢肯定我錯過了一些重要的...> :( – Dolfiz 2011-05-05 09:31:52

回答

0

經過一段時間OptionsTagOptionWriterSelectValueComparator,我會說,那麼「selected」的輸出是基於Object.equals。

因此,如果因任何原因(惰性加載...)對象PracticeT.practiceConfTmodel.put("practiceTypeList", entitiesList)的根據對象是不一樣的(==),那麼forms:options不會選擇它們,只要equals方法不正確實施。

所以我想你需要實現一個正確的equals方法,即使這並沒有解決這個問題,但最好是有一個正確的equals方法而不是一個錯誤的或沒有的方法。


正確實施意味着它必須注意與Hibernate一起使用的事實。 (例如使用if (Hibernate.getClass(this) != Hibernate.getClass(other)),而不是`如果(this.getClass()= other.getClass())

+0

謝謝拉爾夫的建議。你說的話當然是有道理的,但重要的是,在jsp中,在提交後,PracticeConfT爲空。使用我應該能夠顯示其值 - 儘管它的值等於或不等於下拉列表中列出的某個對象 - 而不是它的值。 – Dolfiz 2011-05-05 12:02:57

+0

接縫,我沒有誤解你的問題 - 對不起 – Ralph 2011-05-05 12:16:03