1

I have a single selection table, when i select a row, this exception happens:

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

Here is my Books table:

<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>

And this is 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

I assigned the selected row to selectedBook

Error is cannot convert from type object to Book type.

selectedBook variable type is Book, but which variable is object which causes this error?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • possible duplicate of [Can someone explain "ClassCastException" in Java?](http://stackoverflow.com/questions/907360/can-someone-explain-classcastexception-in-java) – Kukeltje May 01 '15 at 09:04
  • @Kukeltje Not related to this. –  May 01 '15 at 09:14
  • If you learn how to debug, analyze stacktrace etc, you'll see it IS 100 related – Kukeltje May 01 '15 at 09:27
  • 1
    You already got this exception and you were told about it. Why do you try to refer to this list - `List booksList` using array-like indices such as `item[0]`? The exception message indicates that an `Object[]` cannot be (type-)cast to `Book` (`[Ljava.lang.Object;` indicates `Object[].class` - `java.lang.Class` representing the class of array of `Object`s). – Tiny May 01 '15 at 10:12
  • @Tiny Since i'm using hibernate with jsf, the hibernate query returns the `list Of arrays`. –  May 01 '15 at 11:49
  • The combination of jsf and hibernate is NOT the cause of the returning of the listof Arrays... You are since it is code you wrote and hibernate just does as insructed – Kukeltje May 02 '15 at 08:36

2 Answers2

1

You're victim of generic type erasure.

Your List<Book> bookList is actually being filled with List<Object[]>, not List<Book>. This is confirmed by the fact that #{item[0]}, #{item[1]}, etc in your JSF page didn't throw an EL exception. You knew that because of your previous question https://stackoverflow.com/questions/29975635/java-lang-numberformatexception-for-input-string-while-iterating-over-a-pdatat and the answer in the linked duplicate.

You need to fix your Hibernate query in such way that it returns a real List<Book>, not a List<Object[]>. For example, you need to perform a SELECT b FROM Book b instead of SELECT b.id, b.title FROM Book b and set Book.class as return class when creating the query. You should not have need to add a cast on (List<Book>). A bit sane IDE would show an unchecked cast warning on that. That should already have signaled that something is possibly wrong here.

After you've fixed your Hibernate query, you need to make sure that the below test case runs successfully without ClassCastException:

List<Book> books = callYourHibernateQueryHere();

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

Only then you can use rowKey="#{item.id}", #{item.id}, #{item.title}, etc.

Important note that this problem is technically unrelated to JSF. You would have had exactly the same problem when presenting Hibernate results in a different way, such as using System.out.println() as demonstrated above.

If fixing the Hibernate query is not an option for some reason, then you need to replace Book by Object[] over all place in your JSF managed bean. E.g. List<Object[]> bookList, Object[] selectedBook, etc. Needless to say that this is a terrible idea.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Its really complicated problem i ever seen! –  May 01 '15 at 11:36
  • 3
    That is it only when you're brand new to basic Java. It's not wise to already take a deep dive in Java EE while you aren't fluent in basic Java yet. True, Java EE looks exciting and challenging, but I warmly recommend to take a Java EE pause, put aside the Java EE projects, and take some weeks apart to learn some basic Java first. This way you get a better grasp on Java fundamentals such as generics and type erasure in this specific case. In fact, everytime you face an exception of `java.lang.*` package, you've "simply" a basic Java language problem. – BalusC May 01 '15 at 11:39
  • You right, but actually i knew that the problem is about casting, but i would don't know why and how fix it! Then i post this question. –  May 01 '15 at 11:52
  • Because i have some more complicated query in some cases (for example joining multiple tables together and returning from multiple tables) , i can't return a `list if unit class`. So i have to do your second solution. correct? –  May 01 '15 at 12:21
  • You don't have to. It's your choice. I wouldn't recommend it as it only ends up in ugly code. If you can't figure the right Hibernate way, just ask a question to Hibernate guys (or just work through some basic Hibernate tutorials). – BalusC May 01 '15 at 12:21
-3

If you look at the FULL stacktrace, you'll most likely see that the error is in YOUR code. You can and should investigate a classcast exception easily yourself

As a sidenode:

  • value="#{testBean.booksList}" refers to a method in your bean that is NOT shown in the bean code you posted (but very, very relevant, since an individual item in that list is what is in selection)
  • Do you have any clue how the p:dataTable works? I think not. Look at the PF showcase and check all the differences functionalities of it and check the source code and compare with yours
  • You should not only learn some basic jsf/jpa but basic developer skills
Kukeltje
  • 12,223
  • 4
  • 24
  • 47
  • `booksList` is not shown in bean? Are you kidding? Just keep open your eyes. –  May 01 '15 at 09:21
  • The getter is NOT there, just the field. For all we know your getter is wrong. Learn to post MCVE. – Kukeltje May 01 '15 at 09:26
  • 1
    You are welcome... And I don' t mind getting downvoted on answers like this (I even expected it and hoped for it, since my answer deserves it, so it means SO works to a certain extend). What *you* do not get is that by posting partial code, do not do basic investigation, you greatly diminish your chance of actually getting help. And that in future posts you might get ignored. Bon chance... – Kukeltje May 01 '15 at 10:08