[Ljava.lang.Object; cannot be cast to error - java

I get a list from my query.list(). After that, I want to display the object inside this list but I got this error for this line for(Commerce[] c: this.newsList) {
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.model.Commerce;
com.action.CommerceAction.searchCommerces(CommerceAction.java:35)
Here is my code:
My business service
public List<Commerce[]> getCommercesBySearch(String categorie, String lieux) {
Query query = hibUtil.getSession().createQuery("from Commerce c, Categorie ca,Lieux l "
+ "where c.categorie=ca.idCategorie and c.lieux=l.idLieux and"
+ " ca.libelle='" + categorie + "' and l.ville='" + lieux + "' ");
List<Commerce[]> tuples = (List<Commerce[]>) query.list();
return tuples;
}
My action class
private CommerceService service;
private Commerce commerce = new Commerce();
private List<Commerce[]> newsList;
public String searchCommerces() {
String libelle = ServletActionContext.getRequest().getParameter("libelle");
String ville = ServletActionContext.getRequest().getParameter("ville");
this.newsList = service.getCommercesBySearch(libelle,ville);
for(Commerce[] c: this.newsList){
System.out.println(c[0].getNom());
}
if (this.newsList.size() > 0) {
return SUCCESS;
}
addActionError("Il n'existe aucun commerce de cette catégorie dans cette ville");
return ERROR;
}

I am certain that this statement:
List<Commerce[]> tuples = (List<Commerce[]>) query.list();
produces an unchecked type conversion warning. Your code is polluting the heap by doing this unchecked type conversion. query.list() returns a raw List, which will contain Object[]. Here is the relevant Hibernate documentation:
Return the query results as a List. If the query contains multiple results per row, the results are returned in an instance of Object[].
Note that you cannot cast an array to an array of it's sub-type.
There are a couple of ways to fix this problem:
Use List<Object[]> instead of List<Commerce[]>. You can then transform the result of the list() method into a more usable form, preferably within it's own method, before passing it on to the rest of your code. This is the preferable method if you need to select more than just the Commerce object.
Add SELECT c to the beginning of your query, this will allow you to do a safe List<Commerce> cast.

Use select c before your from or you will have some trouble with the returned Object[]. If you don't use this, Hibernate will return a list of Object[] containing more than one object into this. For your problem it will be like:
Object[0] is an instance of Commerce
Object[1] is Categorie
Object[3] is Lieux
etc.
You will throw an ClassCastException if you try to cast Object[] into Commerce.

I think the problem lies here:
Query query = hibUtil.getSession().createQuery("from Commerce c, Categorie ca,Lieux l "
+ "where c.categorie=ca.idCategorie and c.lieux=l.idLieux and"
+ " ca.libelle='" + categorie + "' and l.ville='" + lieux + "' ");
List<Commerce[]> tuples = (List<Commerce[]>) query.list();
That's not correct, considering your idea. I believe that your query should return a List<Commerce>, not List<Commerce[]>.
List<Commerce> tuples = (List<Commerce>) query.list();
To make that works, you need to add SELECT c in your query:
SELECT c from Commerce c, Categorie ca,Lieux l...
It will select a list of object Commerce. If you leave the query like originally, it will return a list of Object array (actually they are Commerce[], Categorie[], Lieux[]...). Not to mention you can't cast directly an array in Java, the objects aren't the same type anyway.

Related

JPA query.getResultList()?

I use JPA 1.0:
Query query;
query = em.createNamedQuery("getThresholdParameters");
query.setParameter(1, Integer.parseInt(circleId));
List<Object[]> resultList = new ArrayList();
resultList = query.getResultList();
Here I get result as List<Object[]>, thus I have to type convert all the parameters of the row to their respective types which is cumbersome.
In JPA 2.0 there is TypedQuery which return an entity object of type one specifies.
But as I am using JPA 1 I can't use it.
How to get result as Entity object of type I want??
EDIT:
QUERY
#Entity
#Table(name="GMA_THRESHOLD_PARAMETERS")
#NamedQuery(
name = "getThresholdParameters",
query = "select gmaTh.minNumberOc, gmaTh.minDurationOc, gmaTh.maxNumberIc, gmaTh.maxDurationIc, gmaTh.maxNumberCellId,"
+ "gmaTh.distinctBnumberRatio, gmaTh.minPercentDistinctBnumber from GmaThresholdParameter gmaTh "
+ "where gmaTh.id.circleId=?1 AND gmaTh.id.tspId=?2 AND gmaTh.id.flag=?3 "
)
Your query selects many fields. Such a query always returns a list of Object arrays. If you want a list containing instances of your GmaThresholdParameter entity, then the query should be
select gmaTh from GmaThresholdParameter gmaTh
where gmaTh.id.circleId=?1 AND gmaTh.id.tspId=?2 AND gmaTh.id.flag=?3
The code to get the list of entities would then be
List<GmaThresholdParameter> resultList = query.getResultList();
You'll get a type safety warning from the compiler, that you can ignore.
I can't respond to this as a comment so I'll just go ahead and make it an answer.
List<Object[]> resultList = new ArrayList(); // CREATE an empty ArrayList object
resultList = query.getResultList(); // getResultList ALSO returns its own ArrayList object
And since you assign the list that getResultList() returns to the same variable as you used for your own empty ArrayList, your application loses any connection to your own empty ArrayList and Java will collect it as garbage. Essentially you created it for absolutely no purpose.
what JB Nizet posted is enough.
List<GmaThresholdParameter> resultList = query.getResultList();
I have done something similar since I was using JPA 1 at that time:
final Collection<YourType> typedResult = new ArrayList<YourType>
for(final Object result : query.getResultList())
{
typedResult.add((YourType) result);
}
return typedResult;
List<GmaThresholdParamerter> result= query.getResultList();
for( GmaThresholdParamerter res : result)
{
System.out.println("" +res.getMinNumberOc());
System.out.println("" +res.getMinDurationOc());
}

What type of list does list() return?

The following query gets the username from the User entity.
String hql = "SELECT userName FROM User WHERE email= :user_email";
Query query = session.createQuery(hql);
query.setParameter("user_email", userSearched );
What type does 'query.list()' return ?
Will it return List?
Actually it will depends upon what type of query that you have used
As i know it will return Two types of List
List<bean>
Contains the whole data records of a table, when you use like createQuery('from table').list() returns this list, because you retrieve all column records from table.
Object[]
When you specify a particluar column name or names like createQuery('select column1,column2 from table').list() , it will return object[], here every column will be retrieved as object[0],object[1],...
Your createQuery(hql).list() will return List and its not typed. From Java Doc
Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].
You specifiy fields in your query.
The query will result a list of Object[].
You can use a Mapper to map these to an object or reference them by index.
createQuery will return object of type List interface i.e. only List. In your case since you know that it will be list of User object to can explicitly cast to List
No. It will return List<Object>
From docs Query#list
public List list()
throws HibernateException
Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].
So, below code will return Object list.
String hql = "SELECT userName FROM User WHERE email='" + userSearched + "'";
List<Object> usersList = sess.createQuery(hql).list();
You can type cast to create ArrayList<User>
String hql = "FROM User WHERE email='" + userSearched + "'"; //changed the query
ArrayList<User> usersList = (ArrayList<User>) sess.createQuery(hql).list();
Not related
I would recommend use Query#setParameter to set the parameter.
String hql = "FROM User WHERE email = :userSearched";
ArrayList<User> usersList = (ArrayList<User>) sess.createQuery(hql).setParameter("userSearched",userSearched).list();

How can i access values returned by Hibernate Query?

How can i access the elements from the list created as below? I tried creating a class containing a String and an int and cast to it but it doesn't work.
List SOList = iadao.getSession().createQuery("select a.sistemOperare, count(a.sistemOperare) from User a, IstoricAfisari b, Banner c, Advertiser d where b.bannerId = c.id and c.advertiserId = d.id and b.userId = a.id group by a.sistemOperare").list();
Thank you
This produces a List of Object arrays -> List<Object[]>
Since the createQuery(HQL).list() returns a List matching the indexes of the selected fields:
List SOList = ...
for (Object obj : SOList) {
Object[] fields = (Object[]) obj;
System.out.println("sistemOperare = " + fields[0] + " (count = " + fields[1] + ")");
}
Would print the results from the query, if any. According to hibernate documentation I could find (Since I'm more used to creating criteria for objects I want and then use Java for the rest).

Generic object returned instead of class entity in hibernate query

I am running a hibernate query which is returning an Object instead of the correct entity object. The statement is as follows:
public List getPriorBids(String rfpCD, String carrierCode) {
String sqlString = " SELECT inland_cd, " +
"rfp_cd, " +
"carrier_cd, " +
"port_cd, " +
"max(iteration_nb) as iteration_nb " +
" FROM care.inland_bid " +
" WHERE rfp_cd = :rfpCode " +
" AND carrier_cd = :carrierCode " +
" GROUP BY inland_cd, rfp_cd, carrier_cd, port_cd " +
" ORDER BY inland_cd, carrier_cd";
SQLQuery sqlQuery = session.createSQLQuery(sqlString);
sqlQuery.setString("carrierCode",carrierCode);
sqlQuery.setString("rfpCode", rfpCD);
sqlQuery.addEntity(Bid.class);
List bids = sqlQuery.list();
return bids;
}
Clearly I am trying to store it as a Bid object. I have another object as well which I should be storing it as but I get an error that the column name cannot be found, despite double and triple checking column names to make sure they match.
Query.list() returns a raw List object, not a generic List.
You should just be able to cast it to List<Bid>, and ignore the unsafe cast warning.
I think you are confusing a method which returns a raw List with the actual run-time type of the List elements being Object. Just because the compile-time signature of List.get(i) returns an Object does not mean that the actual type of the element returned is Object at run-time.
If using JPA 2, you can create a TypedQuery which supports generics

select from two tables using JPQL

I'm using JPQL to retrieve data. I can get data using the statement
List persons = null;
persons = em.createQuery("select p.albumName from PhotoAlbum p , Roleuser r
where r = p.userId and r.userID = 1");
Now I can get the album names using this:
int i=0;
for (i=0;i<persons.size(); i++)
{
System.out.println("Testing n "+ i +" " + persons.get(0));
}
Now I want to get the album name and the roleuser's row named firstname
I'm using the query
persons = em.createQuery("select r.firstName , p.albumName from PhotoAlbum p ,
Roleuser r where r = p.userId and r.userID = 1").getResultList();
Now how do I get the rows firstname and albumname as the persons.get(0) is returning a object
by running the code :
for (i=0;i<persons.size(); i++)
{
//r = (Roleuser) persons.get(i);
System.out.println("Testing n "+ i +" " + persons.get(i));
}
I'm getting this:
Testing n 0 [Ljava.lang.Object;#4edb4077
INFO: Testing n 1 [Ljava.lang.Object;#1c656d13
INFO: Testing n 2 [Ljava.lang.Object;#46dc08f5
INFO: Testing n 3 [Ljava.lang.Object;#654c0a43
How do I map the persons.get(0) and get the firstname and albumname?
Now how do get the rows firstname and albumname as the persons.get(0) is returning a object
Queries with multiple select_expressions in the SELECT clause return an Object[] (or a List of Object[]). From the JPA specification:
4.8.1 Result Type of the SELECT Clause
The type of the query result specified
by the SELECT clause of a query is an
entity abstract schema type, a
state-field type, the result of an
aggregate function, the result of a
construction operation, or some
sequence of these.
The result type of the SELECT clause
is defined by the the result types of
the select_expressions contained in
it. When multiple
select_expressions are used in the SELECT clause, the result of the query
is of type Object[], and the
elements in this result correspond in
order to the order of their
specification in the SELECT clause and
in type to the result types of each of
the select_expressions.
So in your case, you probably want something like this:
for (i=0;i<persons.size(); i++) {
//r = (Roleuser) persons.get(i);
System.out.println("Testing n " + i + " " + persons.get(i)[0] + ", " +
persons.get(i)[1]);
}
Note that specifying an inner join by the use of a cartesian product in the FROM clause and a join condition in the WHERE clause is less typical than specifying an explicit join over entity relationships (using the [LEFT [OUTER] | INNER ] JOIN syntax). See the whole section 4.4.5 Joins in the specification.
References
JPA 1.0 Specification
Section 4.8.1 "Result Type of the SELECT Clause"
Section 4.8.2 "Constructor Expressions in the SELECT Clause"
Section 4.4.5 "Joins"

Categories