Using Seam 2.0.1.GA and JBoss 4.2.1.GA with Hibernate 3.2.4.sp1
I'm seeing the following exception on my screen when my facelet is being rendered:
Quote:
javax.faces.FacesException: javax.el.PropertyNotFoundException: /TechDeployToUser.xhtml @147,72 value="#{hardware.tbHardwareNotes.hardwareNote}": Property 'hardwareNote' not found on type org.hibernate.collection.PersistentSet
Here is what is going on and my workaround but I'd like to know why this exception is being thrown... thx.
There is a 1:M relationship b/n TbHardware and TbHardwareNote defined as follows by ORM annotations:
Code:
@Entity
@Table(name = "tbHardware")
@Name("tbHardware")
public class TbHardware implements java.io.Serializable {
…
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "tbHardware")
public Set<TbHardwareNote> getTbHardwareNotes() {
return this.tbHardwareNotes;
}
…
}
Code:
@Entity
@Table(name = "tbHardwareNote")
public class TbHardwareNote implements java.io.Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "HardwareID", nullable = false)
public TbHardware getTbHardware() {
return this.tbHardware;
}
}
JPA query:
Code:
hardwareTableList = entityManager.createQuery("SELECT hardware "+
"FROM UTbUser user, " +
" TbLocation location, "+
" TbHardware hardware, "+
" TbHardwareVendor vendor, "+
" TrOwnerType owner, "+
" TrHardwareType type, "+
" TbHardwareModel model, "+
" TrHardwareStatus hwstatus "+
"WHERE user.networkLogin = :networkLogin AND "+
" user.userId = location.userId AND "+
" location.locationNo = hardware.tbLocation.locationNo AND "+
" hardware.trHardwareStatus.hardwareStatus = :hardwareStatus AND "+
" hardware.trOwnerType.ownerTypeCode = owner.ownerTypeCode AND "+
" hardware.tbHardwareModel.hardwareModelId = model.hardwareModelId AND "+
" model.tbHardwareVendor.hardwareVendorId = vendor.hardwareVendorId AND "+
" model.trHardwareType.hardwareTypeId = type.hardwareTypeId AND "+
" hardware.trHardwareStatus.hardwareStatus = hwstatus.hardwareStatus "+
" ORDER BY hardware.coxBarcode")
.setParameter("networkLogin", networkLogin)
.setParameter("hardwareStatus", SHIMSConstants.ASSIGN_TO_TECH_STATUS_ID)
.getResultList();
I tried changing the FetchType to EAGER for both getter methods, didn’t help, still getting the exception.
So I tried a method I learned from Pete Muir and the exception is gone now and the note column displays the proper data. The solution is to return multiple entities in the result list and access them via the Object[] array. In this case it would be foobar[0].coxBarcode (references TbHardware entity) and foobar[1].hardwareNote (references TbHardwareNote entity).
Code:
hardwareTableList = entityManager.createQuery("SELECT hardware, note "+
"FROM UTbUser user, " +
" TbLocation location, "+
" TbHardware hardware, "+
" TbHardwareVendor vendor, "+
" TrOwnerType owner, "+
" TrHardwareType type, "+
" TbHardwareModel model, "+
" TrHardwareStatus hwstatus, "+
" TbHardwareNote note "+
"WHERE user.networkLogin = :networkLogin AND "+
" user.userId = location.userId AND "+
" location.locationNo = hardware.tbLocation.locationNo AND "+
" hardware.trHardwareStatus.hardwareStatus = :hardwareStatus AND "+
" hardware.trOwnerType.ownerTypeCode = owner.ownerTypeCode AND "+
" hardware.tbHardwareModel.hardwareModelId = model.hardwareModelId AND "+
" model.tbHardwareVendor.hardwareVendorId = vendor.hardwareVendorId AND "+
" model.trHardwareType.hardwareTypeId = type.hardwareTypeId AND "+
" hardware.trHardwareStatus.hardwareStatus = hwstatus.hardwareStatus AND "+
" hardware.hardwareId = note.tbHardware.hardwareId "+
" ORDER BY hardware.coxBarcode")
.setParameter("networkLogin", networkLogin)
.setParameter("hardwareStatus", SHIMSConstants.ASSIGN_TO_TECH_STATUS_ID)
.getResultList();
Code:
<rich:dataTable id="techQueueTable" value="#{hardwareTableList}" var="hardware" columnClasses="center">
<rich:column>
<f:facet name="header"><h:outputText value="Barcode"/></f:facet>
<h:outputText value="#{hardware[0].coxBarcode}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Purchaser"/></f:facet>
<h:outputText value="#{hardware[0].trOwnerType.ownerTypeDesc}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Manufacturer"/></f:facet>
<h:outputText value="#{hardware[0].tbHardwareModel.tbHardwareVendor.hardwareVendorDesc}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Type"/></f:facet>
<h:outputText value="#{hardware[0].tbHardwareModel.trHardwareType.hardwareTypeDesc}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Model"/></f:facet>
<h:outputText value="#{hardware[0].tbHardwareModel.hardwareModel}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Date Assigned"/></f:facet>
<h:outputText value="#{hardware[0].firstEnteredDate}">
<f:convertDateTime pattern="MM/dd/yyyy"/>
</h:outputText>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Notes"/></f:facet>
<h:outputText value="#{hardware[1].hardwareNote}"/>
</rich:column>
<rich:column>
<f:facet name="header"><h:outputText value="Assign To User"/></f:facet>
<h:selectBooleanCheckbox value="#{hardware[0].isSelected}"/>
</rich:column>
</rich:dataTable>
This is the code in the facelet that was causing the error:
Code:
<rich:column>
<f:facet name="header"><h:outputText value="Notes"/></f:facet>
<h:outputText value="#{hardware.tbHardwareNotes.hardwareNote}"/>
</rich:column>