Problem with bijecting
newlukai Mar 8, 2006 4:30 AMHi,
I'm encountering a problem with bijecting and don't know how to solve it. I think for you it's an obvious mistake I made, but I don't have any idea.
Like the hotel list in the booking example I've a list of elements in my application. Each of them has an ID, which is clickable. After a click on an elements ID, the user is navigated to a page (let's call it detailPage) which shows the details of the selected element. This works fine.
I've a class (Seam component) for each one of the two pages, ShowList and ShowElement. The ShowList class keeps the DataModel and DataModelSelection. Clicking on an element the DataModelSelection is passed to detailPage. The element is injected in the ShowElement class, where I use it to show some additional information related to this element.
Now I want to add the possibility to change some details. After saving the changes the next element should be shown to the user.
Therefore I added a commandButton (submit) which calls a method in ShowElement, which saves the changes. Then I want to get the next element of the list and outject it to the same page. But as soon as the user clicks the submit button, the element is nulled. I would expect that the changed element is injected, which then could be saved.
There is some code, which hopefully explains my problem:
The component keeping the list:
@Stateful @Scope(ScopeType.SESSION) @LoggedIn @Name("showListForDevelopers") @Interceptors(SeamInterceptor.class) public class ShowListForDevelopers implements IShowListForDevelopers, Serializable { @PersistenceContext(unitName = "aresDatabase", type=PersistenceContextType.EXTENDED) private EntityManager em; @In @Valid private User user; @DataModel private List<Testaction> testactions; @DataModelSelection @Out(required = false) private Testaction currentTestaction; @Factory("testactions") public void getTestactions() { testactions = em.createQuery( "from Testaction where TACT_DEV_USR_ID=:dev order by TACT_ID asc" ).setParameter("dev", user.getID()).getResultList(); } public String select() { return "selected"; } @Remove @Destroy public void destroy() { } }
I skip the page displaying the list, it's a simple dataTable.
The page showing the element (not the complete page):
<h:form> <div class="errors"> <h:messages globalOnly="true" /> </div> <div class="buttonBox"> <h:commandButton action="#{showTestactionForDevelopers.saveTestaction}" value="Save and Next" class="button" type="submit" immediate="true" /> </div> <table cellpadding="0" cellspacing="0" border="0"> <tr> <th><h:outputText value="#{ares_messages.label_testaction_ID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_TDate}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_TCaseID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_TesterUsrID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_EnvID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_SevID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_EditorUsrID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_DevUsrID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_RevID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_ChnglistID}" /></th> <th><h:outputText value="#{ares_messages.label_testaction_ValidatorUsrID}" /></th> <th> </th> </tr> <tr> <td><h:outputText value="#{currentTestaction.ID}" /></td> <td><h:outputText value="#{currentTestaction.TDate}" /></td> <td> <h:selectOneMenu value="#{currentTestaction.TCaseID}"> <f:selectItems value="#{showTestactionForDevelopers.testcases}" /> </h:selectOneMenu> </td> <td><h:outputText value="#{currentTestaction.testerUsrID}" /></td> <td><h:outputText value="#{currentTestaction.envID}" /></td> <td><h:outputText value="#{currentTestaction.sevID}" /></td> <td><h:outputText value="#{currentTestaction.editorUsrID}" /></td> <td> <h:selectOneMenu value="#{currentTestaction.devUsrID}"> <f:selectItems value="#{showTestactionForDevelopers.developers}" /> </h:selectOneMenu> </td> <td> <h:selectOneMenu value="#{currentTestaction.revID}"> <f:selectItems value="#{showTestactionForDevelopers.revisions}" /> </h:selectOneMenu> </td> <td><h:inputText value="#{currentTestaction.chnglistID}" /></td> <td><h:outputText value="#{currentTestaction.validatorUsrID}" /></td> <td> </td> </tr> </table> </h:form>
The component which should save the element:
@Stateful @Scope(ScopeType.SESSION) @LoggedIn @Name("showTestactionForDevelopers") @Interceptors(SeamInterceptor.class) public class ShowTestactionForDevelopers implements IShowTestactionForDevelopers{ @PersistenceContext(unitName = "aresDatabase", type = PersistenceContextType.EXTENDED) private EntityManager em; @In(required=false) @Out(scope=ScopeType.EVENT) //@In(required=false) just for test purposes @Valid private Testaction currentTestaction; @In @Valid private User user; private List<Testcase> testcases; private List<User> developers; private List<Revisionclass> revisions; private List<Testaction> testactions; public String saveTestaction() { System.out.println("Saving testaction " + currentTestaction.getID()); if(testactions == null) { testactions = em.createQuery( "from Testaction where TACT_DEV_USR_ID=:dev order by TACT_ID asc" ).setParameter("dev", user.getID()).getResultList(); } ListIterator<Testaction> testactionsIter = testactions.listIterator(testactions.indexOf(currentTestaction)); if(testactionsIter.hasNext()) { currentTestaction = testactionsIter.next(); return "next"; } return "noMore"; } public SelectItem[] getTestcases() { List<Testcase> testcasesFromDB; if(testcases == null || testcases.get(0).getTObjID() != currentTestaction.getTObjID()) { testcasesFromDB = em.createQuery( "from Testcase where TCASE_TOBJ_ID=:tobj order by TCASE_ID asc" ).setParameter("tobj", currentTestaction.getTObjID()).getResultList(); } else { testcasesFromDB = testcases; } SelectItem[] result = new SelectItem[testcasesFromDB.size()]; for(int i = 0; i < testcasesFromDB.size(); i++) { Testcase testcase = testcasesFromDB.get(i); result = new SelectItem(testcase.getID(), testcase.getID() + " - " + testcase.getToken()); } return result; } public SelectItem[] getDevelopers() { if(developers == null) { developers = em.createQuery( "from User where USR_ISDEVELOPER=-1 order by USR_NAME asc" ).getResultList(); } SelectItem[] result = new SelectItem[developers.size()]; for(int i = 0; i < developers.size(); i++) { User user = developers.get(i); result = new SelectItem(user.getID(), user.getID() + " - " + user.getName()); } return result; } public SelectItem[] getRevisions() { if(revisions == null) { revisions = em.createQuery( "from Revisionclass order by REV_ID asc" ).getResultList(); } SelectItem[] result = new SelectItem[revisions.size()]; for(int i = 0; i < revisions.size(); i++) { Revisionclass revision = revisions.get(i); result = new SelectItem(revision.getID(), revision.getID() + " - " + revision.getDescr()); } return result; } public Long getSelectedTestcase() { if(currentTestaction == null) { return new Long(-1); } return currentTestaction.getTCaseID(); } public String getSelectedDeveloper() { if(currentTestaction == null) { return ""; } return currentTestaction.getDevUsrID(); } public Integer getSelectedRevision() { if(currentTestaction == null) { return new Integer(-1); } return currentTestaction.getRevID(); } @Destroy @Remove public void destroy() { } }
Please let me know if there are some questions left.
Thanks
Newlukai