nested dataTable -- one-to-many relations
ralphbca May 9, 2006 2:17 AMHi,
I have the following one-to-many relations:
ExceptionReport -* PartAffected -* LotNumber
I want to provide the user with a summary page that lists an ExceptionReport with all the PartsAffected and the LotNumbers for each PartAffected. The user sees a list of ExceptionReports and clicks on a button to get the details of the report.
My problem is that I cannot get the lotNumbers displayed. I did not find a similar example in the sample seam apps.
Here is the code that loads the ExceptionReport, the PartsAffected are in a DataModel and then displayed using a facelets dataTable:
@Stateful @Name("managerAccept") @Conversational(ifNotBegunOutcome="admin") @LoggedIn @Interceptors(SeamInterceptor.class) public class ManagerAcceptAction implements ManagerAccept, Serializable { static Logger logger = Logger.getLogger(ManagerAcceptAction.class); @In(value="currentUser") User admin; @PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager em; @Out ExceptionReport exceptionReport; @DataModel(value="partsAffected") public List<PartAffected> partsAffected; @DataModelSelection(value="partsAffected") public PartAffected partAffected; @In long reportId; @BeginTask public String viewTask() { logger.info("Retrieving exception report number: " + reportId); exceptionReport = (ExceptionReport) em.createQuery("from ExceptionReport er where er.exceptionReportId = :reportId") .setParameter("reportId", reportId) .getSingleResult(); partsAffected = new ArrayList( exceptionReport.getPartsAffected() ); if ( partsAffected != null ){ logger.info("Retrieved " + partsAffected.size() + " parts affected"); } for (PartAffected part: partsAffected){ if ( part.getLotNumbers() != null ){ logger.info("Part " + part.getName() + " Number of lots " + part.getLotNumbers().size() ); } else{ logger.info("No LotNumbers associated with partAffected: " + part.getName() ); } } return "managerAccept"; } @EndTask(transition="approve") public String accept() { exceptionReport.process(); return "admin"; } @EndTask(transition="reject") public String reject() { exceptionReport.reject(); if (admin instanceof Admin) { return "admin"; } else{ return "index"; } } @Destroy @Remove public void destroy() {} }
The ExceptionReport -* PartAffected -* LotNumber relations:
ExceptionReport.java: @OneToMany(mappedBy="exceptionReport", cascade=CascadeType.REMOVE) public Set<PartAffected> getPartsAffected() { return this.partsAffected; } public void setPartsAffected(Set<PartAffected> partsAffected) { this.partsAffected = partsAffected; } PartAffected.java: @OneToMany(mappedBy="partAffected", cascade=CascadeType.REMOVE) public Set<LotNumber> getLotNumbers() { return this.lotNumbers; } public void setLotNumbers(Set<LotNumber> lotNumbers) { this.lotNumbers = lotNumbers; }
Here is the page that displays the exception report:
<div class="cntInfo"> <h:panelGrid id="acceptReportGrid" columns="2"> <h:outputText value="Exception Number:" /> <h:outputText value="#{exceptionReport.exceptionNumber}" /> <h:outputText value="Status:" /> <h:panelGroup> <h:outputText value="#{exceptionReport.status}" /> </h:panelGroup> <h:outputText value="Description:" /> <h:outputText value="#{exceptionReport.description}"/> <h:outputText value="Attachments:" /> <h:outputText value="#{exceptionReport.attachment}"/> <h:outputText value="Report created:" /> <h:outputText value="#{exceptionReport.dateCreated}"> <f:convertDateTime timeZone="PST" type="both" dateStyle="full"/> </h:outputText> <h:outputText value="Exception Observed:" /> <h:outputText value="#{exceptionReport.dateOfException}"> <f:convertDateTime timeZone="PST" type="date" pattern="yyyy-MM-dd" dateStyle="short"/> </h:outputText> <h:panelGrid id="partsNlotsGrid" columns="1"> <h:dataTable value="#{partsAffected}" id="partsAffected" var="part" styleClass="dvdtable" headerClass="dvdtablehead" rowClasses="dvdtableodd,dvdtableeven" columnClasses="dvdtablecol"> <h:column> <f:facet name="header">Documents or Parts Affected:</f:facet> <h:outputText value="#{part.name}"/> <h:dataTable value="#{part.lotNumbers}" var="lotItem" rendered="#{not empty part.lotNumbers}" id="itemList"> <f:facet name="header">Lot Numbers:</f:facet> <h:outputText value="#{lotItem.name}"/> </h:dataTable> </h:column> </h:dataTable> </h:panelGrid> </h:panelGrid> <h:form> <h:commandButton action="#{managerAccept.reject}" value="Reject Report" /> <h:commandButton action="#{managerAccept.accept}" value="Accept Report" /> </h:form> </div>
Listing the PartsAffected works fine, but I cannot see the the LotNumber name ( #{lotNumber.name} ). However, the header for the lotNumber section is displayed only if there are lotNumbers ( the "rendered=#{not empty part.lotNumbers}" seems to work ). I am at a loss on how to get the lotNumber information displayed. Can anybody provide me with some pointers on how to get this displayed properly.
Thanks a lot in advance!