0

Upon trying to retrieve a table from database through JPA and fill it into the Table SWT widget (org.eclipse.swt.widgets.Table), I get a cast error while executing the following Java code:

EntityManager connection = DB.Connection().createEntityManager(); //the EntityManagerFactory
TypedQuery<Object[]> query = (TypedQuery<Object[]>) connection.createQuery("select t from Test t"); 
List<Object[]> tablelist = query.getResultList();
connection.close();

SWTtable.removeAll(); //clears all the elements in the table

for (Object[] row : tablelist) { //error on this line - java.lang.ClassCastException: {packagename}.Test cannot be cast to [Ljava.lang.Object;
    final TableItem item = new TableItem(SWTtable, SWT.None);
    item.setData(row[0]);
    item.setText(0, row[1].toString());
}

As seen above, this line for (Object[] row : tablelist) { returns an error of java.lang.ClassCastException: {packagename}.Test cannot be cast to [Ljava.lang.Object;

It seems that there is an error casting tablelist which is List<Object[]> to Object[] row in the foreach loop. I have tried various solutions, but cannot figure this out as I need to retain the option of Object[] array in order to have all the row elements at my disposal as items for the SWT table. Everything else works fine except this line of code. If it's set to for (Object row : tablelist), so no array. Then there is no error, but I lose the array and thus lose the option to have all the elements at my disposal as items for the SWT table.

If this is a bad approach and you have other suggestions, please specify.

Note: The SQL query, "select t from Test t" is just testing code. I will use a parmeter to specify which records I need later, so there will be more then one table here.

Joe Barr
  • 251
  • 3
  • 10

3 Answers3

1

This will work, the exception is also telling you what is wrong. Test here is a JPA type, it is your typecast one line 2 that is incorrect. Your typecast is forcing a List< Test > to a List< Object[] >.

The javadoc Execute a SELECT query and return the query results as a typed List.

item.setData and item.setText should invoke the correct attribute accessor in row

EntityManager connection = DB.Connection().createEntityManager(); //the EntityManagerFactory
TypedQuery<Test> query = (TypedQuery<Test>) connection.createQuery("select t from Test t"); 
List<Test> tablelist = query.getResultList();
connection.close();

SWTtable.removeAll(); //clears all the elements in the table

for (Test row : tablelist) { //error on this line - java.lang.ClassCastException {packagename}.Test cannot be cast to [Ljava.lang.Object;
    final TableItem item = new TableItem(SWTtable, SWT.None);
    item.setData(row.getSomeAttribute());
    item.setText(0, row.getSomeOtherAttribute());
}
Bhaskar
  • 524
  • 2
  • 10
  • For me List tablelist = query.getResultList(); cannot remain an List. It says, change type of tablelist to List and if I change that I'm back to square one again. No objects and no array. – Joe Barr Jan 24 '14 at 00:08
  • Ahh I missed one location when I edited your code, you are correct, it is a List which I mentioned in the original reply. – Bhaskar Jan 24 '14 at 00:18
  • @Bhasker I managed to solve it, but now I have another error. Are you willing to help? – Joe Barr Jan 24 '14 at 01:59
  • @JoeBarr why don't you just ask your question and I am sure someone will answer, feel free to ping me in a comment – Bhaskar Jan 24 '14 at 03:35
  • @Bhasker Yes, that is what I meant. – Joe Barr Jan 24 '14 at 10:04
  • Here it is: http://stackoverflow.com/questions/21343839/string-search-runtime-error-in-jpa-sql-query-jpql – Joe Barr Jan 24 '14 at 22:49
0

It looks like tableList contains a list of Test objects, not a list of Object arrays. That is why when you changed it to

for (Object row : tablelist)

the code worked.

Try changing

List<Object[]> tablelist = query.getResultList();

to

List<Test> tablelist = query.getResultList();

and change

for (Object[] row : tablelist) {
    ...
}

to

for (Test row : tablelist) {
    ...
}

You will have to change the code in the for-loop to work with the Testobject instead of the Object[]. Without knowing what the Test object holds, it's hard for me to tell you how that would be done. But I would think the Test object should hold all the information that you are trying to retrieve from the array because that is how your information is being returned.

mdewitt
  • 2,464
  • 17
  • 23
  • Yes, I know that, but then I lose the row array. The code was running like this, but now it has to be changed to an array of objects no matter what they are. They are tables, and you are correct about the information in table Test. – Joe Barr Jan 23 '14 at 22:56
  • The only problem is for (Object[] row : tablelist), whatever else is changed works, except for this line. It only works as Object and not an array of the same. – Joe Barr Jan 23 '14 at 22:58
  • I am not an expert in this area, but I think you would have to create one object that holds all the types (tables) you are returning. Did you look at this stackoverflow question? http://stackoverflow.com/questions/10807496/error-cannot-create-typedquery-for-query-with-more-than-one-return – mdewitt Jan 23 '14 at 23:01
  • Actually yes. My code was setup like that, but I decided to cast it instead of sending a parameter class. It works the same, or doesn't in my case. – Joe Barr Jan 23 '14 at 23:08
0

I solved the error like this:

"select t.id, t.first, t.second, t.last from Test t"

it was all in the SQL query. I had to define the attributes instead of just selecting all the attributes like this:

"select t from Test t"
mdewitt
  • 2,464
  • 17
  • 23
Joe Barr
  • 251
  • 3
  • 10