java.util.Vector cannot be cast to javax.faces.model.DataModel
waltc Mar 8, 2011 10:02 AMI have the following code:
`@Name("DailyActivity")
public class DailyActivityBean implements DailyActivity {
@DataModel
protected List<ActivityDay> dayList;
@Factory("dayList")
public List<ActivityDay> createDayList() {
List<ActivityDay> dayList = new Vector<ActivityDay>();
buildDataList(); // build tree keyed on date with value of ActivityDay object
for (String day : dayBean.keySet()) {
ActivityDay aDay = dayBean.get(day);
dayList.add(aDay);
}
statusMessages.add(Severity.INFO, "created " + dayList.size() + " day elements");
return dayList;
}
`
` <f:facet name="label">
<h:panelGroup><h:graphicImage style="vertical-align: middle; padding-right: 4px;"/>Grid (#{dayList.size()})</h:panelGroup>
</f:facet>
<div class="results">
<rich:dataTable value="#{dayList}" var="_day"
columnClasses="left, right"
`
From the writeup in Dan's book I should be using Factory rather than outjecting. Also, in his example of 'newGolfers' the @Factory method was a void. I patterned my code after his. This worked fine, a void return, except the dayList returned was always empty, even though the statusMessage said it added 262 entries.
According to the text of Dan's book:
The first time the #{newGolfers} value expression is encountered in the JSF view, the
newGolfers context variable is uninitialized. Seam will turn to the @Factory method D
to resolve a value. Before the method proceeds the EntityManager property B is
injected. The method then uses the EntityManager to query the database for the newest
golfers E, shuffles the result, and pares it down to the configured display size F. Out-
jection is then applied, which initializes the newGolfers context variable as a JSF Data-
Model C. Seam then returns control to the view renderer, which uses the newly formed
data model to render the <rich:dataList>.
This doesn't appear to have happened. When I made the @Factory return the List<ActivityDay> the datagrid was automatically populated, the first time. If I depress display button I get the exception of classcastexception saying the List<ActivityDay> cannot be cast to DataModel.
`<h:form styleClass="edit">
<rich:simpleTogglePanel>
<f:facet name="header">Activity Filter</f:facet>
<h:panelGrid columns="4" width="20%" height="20%">
<rich:column width="20%">Engine Type
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityEngineType" value="#{compositeActivityList.engineType}" abel="Engine" required="true" selectFirstOnUpdate="true">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Country
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityCountry" suggestionValues="#{DailyActivity.engines}" value="#{compositeActivityList.country}" label="Country" required="false">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Document Type
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityDocType" suggestionValues="#{DailyActivity.docs}" directInputSuggestions="true" label="Document" required="true" value="#{compositeActivityList.docType}" selectFirstOnUpdate="true">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Smoothing factor
<s:decorate template="layout/display.xhtml">
<rich:inputNumberSpinner id="smoothingSpinner" label="Smoothing Period" maxValue="21" minValue="1" step="1" value="#{DailyActivity.smoothing}">
</rich:inputNumberSpinner>
</s:decorate>
</rich:column>
</h:panelGrid>
<div class="actionButtons">
<h:commandButton id="Display" value="Display" rerender="output"/>
<s:button id="reset" value="Reset" includePageParams="false"/>
</div>
</rich:simpleTogglePanel>
</h:form>
`
What is really interesting is the exception stacktrace shows:
`Caused by java.lang.ClassCastException with message: "java.util.Vector cannot be cast to javax.faces.model.DataModel"
org.jboss.seam.databinding.DataModelBinder.getSelection(DataModelBinder.java:14)
org.jboss.seam.Component.injectDataModelSelection(Component.java:1638)
org.jboss.seam.Component.injectDataModelSelections(Component.java:1619)
org.jboss.seam.Component.inject(Component.java:1558)
org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61)
org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
com.monster.analytics.action.DailyActivityBean_$$_javassist_seam_3.getSmoothing(DailyActivityBean_$$_javassist_seam_3.java)
`
`@Name("DailyActivity")
public class DailyActivityBean implements DailyActivity {
@DataModel
protected List<ActivityDay> dayList;
@Factory("dayList")
public List<ActivityDay> createDayList() {
List<ActivityDay> dayList = new Vector<ActivityDay>();
buildDataList(); // build tree keyed on date with value of ActivityDay object
for (String day : dayBean.keySet()) {
ActivityDay aDay = dayBean.get(day);
dayList.add(aDay);
}
statusMessages.add(Severity.INFO, "created " + dayList.size() + " day elements");
return dayList;
}
`
` <f:facet name="label">
<h:panelGroup><h:graphicImage style="vertical-align: middle; padding-right: 4px;"/>Grid (#{dayList.size()})</h:panelGroup>
</f:facet>
<div class="results">
<rich:dataTable value="#{dayList}" var="_day"
columnClasses="left, right"
`
From the writeup in Dan's book I should be using Factory rather than outjecting. Also, in his example of 'newGolfers' the @Factory method was a void. I patterned my code after his. This worked fine, a void return, except the dayList returned was always empty, even though the statusMessage said it added 262 entries.
According to the text of Dan's book:
The first time the #{newGolfers} value expression is encountered in the JSF view, the
newGolfers context variable is uninitialized. Seam will turn to the @Factory method D
to resolve a value. Before the method proceeds the EntityManager property B is
injected. The method then uses the EntityManager to query the database for the newest
golfers E, shuffles the result, and pares it down to the configured display size F. Out-
jection is then applied, which initializes the newGolfers context variable as a JSF Data-
Model C. Seam then returns control to the view renderer, which uses the newly formed
data model to render the <rich:dataList>.
This doesn't appear to have happened. When I made the @Factory return the List<ActivityDay> the datagrid was automatically populated, the first time. If I depress display button I get the exception of classcastexception saying the List<ActivityDay> cannot be cast to DataModel.
`<h:form styleClass="edit">
<rich:simpleTogglePanel>
<f:facet name="header">Activity Filter</f:facet>
<h:panelGrid columns="4" width="20%" height="20%">
<rich:column width="20%">Engine Type
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityEngineType" value="#{compositeActivityList.engineType}" abel="Engine" required="true" selectFirstOnUpdate="true">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Country
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityCountry" suggestionValues="#{DailyActivity.engines}" value="#{compositeActivityList.country}" label="Country" required="false">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Document Type
<s:decorate template="layout/display.xhtml">
<rich:comboBox id="compositeActivityDocType" suggestionValues="#{DailyActivity.docs}" directInputSuggestions="true" label="Document" required="true" value="#{compositeActivityList.docType}" selectFirstOnUpdate="true">
</rich:comboBox>
</s:decorate>
</rich:column>
<rich:column width="20%">Smoothing factor
<s:decorate template="layout/display.xhtml">
<rich:inputNumberSpinner id="smoothingSpinner" label="Smoothing Period" maxValue="21" minValue="1" step="1" value="#{DailyActivity.smoothing}">
</rich:inputNumberSpinner>
</s:decorate>
</rich:column>
</h:panelGrid>
<div class="actionButtons">
<h:commandButton id="Display" value="Display" rerender="output"/>
<s:button id="reset" value="Reset" includePageParams="false"/>
</div>
</rich:simpleTogglePanel>
</h:form>
`
What is really interesting is the exception stacktrace shows:
`Caused by java.lang.ClassCastException with message: "java.util.Vector cannot be cast to javax.faces.model.DataModel"
org.jboss.seam.databinding.DataModelBinder.getSelection(DataModelBinder.java:14)
org.jboss.seam.Component.injectDataModelSelection(Component.java:1638)
org.jboss.seam.Component.injectDataModelSelections(Component.java:1619)
org.jboss.seam.Component.inject(Component.java:1558)
org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61)
org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
com.monster.analytics.action.DailyActivityBean_$$_javassist_seam_3.getSmoothing(DailyActivityBean_$$_javassist_seam_3.java)
`