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!