p:dataTable javax.el.E​​LException:selection ="#{testBean.selectedBook}无法从Object转换为Book

时间:2015-05-01 08:54:19

标签: hibernate jsf primefaces datatable

我有一个single选择表,当我选择一行时,会发生以下异常:

com.sun.faces.context.PartialViewContextImpl.processPartial javax.el.ELException: /Test.xhtml @18,79 selection="#{testBean.selectedBook}": Cannot convert [Ljava.lang.Object;@5b9b0639 of type class [Ljava.lang.Object; to class com.obs.model.Book
javax.el.ELException: /Test.xhtml @18,79 selection="#{testBean.selectedBook}": Cannot convert [Ljava.lang.Object;@5b9b0639 of type class [Ljava.lang.Object; to class com.obs.model.Book

Caused by: javax.el.ELException: Cannot convert [Ljava.lang.Object;@5b9b0639 of type class [Ljava.lang.Object; to class com.obs.model.Book

这是我的图书表:

<h:form>
    <p:dataTable id="singleDT" var="item" value="#{testBean.booksList}" selectionMode="single"
                 selection="#{testBean.selectedBook}" rowKey="#{item[0]}">

        <p:ajax event="rowSelect" listener="#{testBean.onRowSelect}"/>
        <p:ajax event="rowUnselect" listener="#{testBean.onRowUnselect}"/>

        <p:column headerText="Id">
            <h:outputText value="#{item[0]}"/>
        </p:column>
        <p:column headerText="Title">
            <h:outputText value="#{item[1]}"/>
        </p:column>
        <f:facet name="footer">
            <p:commandButton process="singleDT" icon="ui-icon-search" value="View" action="#{testBean.showPlease}"/>
        </f:facet>
    </p:dataTable>
</h:form>

这是testBean

private List<Book> booksList;
private Book selectedBook;

public Book getSelectedBook() {
    return selectedBook;
}

public void setSelectedBook(Book selectedBook) {
    this.selectedBook = selectedBook;
}

public void onRowSelect(SelectEvent event) {
    System.out.println("row selected, " + event.getObject()); // displays [Ljava.lang.Object;@62699e1d
}

public void onRowUnselect(UnselectEvent event) {
    System.out.println("row Unselected");
}

@Transactional
public List<Book> allBooks() {
// fill the list with hibernate
    return booksList;
}

//getter/setters

我已将所选行分配到selectedBook

错误无法从object类型转换为Book类型。

selectedBook变量类型为Book,但哪个变量为object会导致此错误?

2 个答案:

答案 0 :(得分:1)

您是通用类型擦除的受害者。

List<Book> bookList 实际List<Object[]>填充,而不是List<Book>。事实证明,JSF页面中的#{item[0]}#{item[1]}等没有抛出EL异常。您知道这是因为您之前的问题https://stackoverflow.com/questions/29975635/java-lang-numberformatexception-for-input-string-while-iterating-over-a-pdatat和链接副本中的答案。

您需要修复Hibernate查询,使其返回真实的List<Book>,而不是List<Object[]>。例如,您需要在创建查询时执行SELECT b FROM Book b而不是SELECT b.id, b.title FROM Book b并将Book.class设置为返回类。您不需要在(List<Book>)上添加强制转换。一点点理智的IDE会显示未经检查的强制警告。这应该已经表明这里可能出现了问题。

在您修复了Hibernate查询后,您需要确保以下测试用例在没有ClassCastException的情况下成功运行:

List<Book> books = callYourHibernateQueryHere();

for (Book book : books) {
    System.out.println(book.getTitle());
}

只有这样,您才能使用rowKey="#{item.id}"#{item.id}#{item.title}等。

重要提示,此问题在技术上与JSF无关。在以不同的方式呈现Hibernate结果时,您会遇到完全相同的问题,例如使用上面演示的System.out.println()

如果出于某种原因无法修复Hibernate查询,那么您需要在{JSF>托管bean的所有位置替换Book Object[]。例如。 List<Object[]> bookListObject[] selectedBook等。不用说这是一个糟糕的主意。

答案 1 :(得分:-3)

如果你看一下FULL堆栈跟踪,你很可能会发现错误在你的代码中。您可以而且应该自己轻松调查一个转发异常

作为副节点:

  • value="#{testBean.booksList}"指的是bean中未显示在您发布的bean代码中的方法(但非常非常相关,因为该列表中的单个项目是选择中的内容)
  • 你有什么线索p:dataTable works?我想不是。查看PF展示并检查它的所有差异功能并检查源代码并与您的比较
  • 您不仅应该学习一些基本的jsf / jpa,还应该学习基本的开发人员技能