I wrote this code to set the a jTable to a model to suit the data that would be returned from my query. I am not sure why this is happening but I do have an example of the same code in use and it works perfectly.
Note: the query calls records from a table that is linked to another table.
Note: Some may say this is a duplicate question but I feel not becuase Ilooked at that question and non of the solutions helped me, I tried using the iterator instead but same error occurs.
Any suggestions.
This is the code
public void createModelsAndEquipmentTableModel(){
Query query = FinancialDBPUEntityManager.createQuery("SELECT t FROM Stocktbl t WHERE t.chemical = FALSE");
List<Object[]> results = query.getResultList();
String headings[] = {"Product ID", "Product Name", "Number In Stock", "Number Needs Replacing"};
Object data[][] = new Object[results.size()][headings.length];
int index = 0;
for(Object[] obj: results){// error occurs here.
data[index++] = obj;
}
DefaultTableModel model = new DefaultTableModel(data, headings);
tblquipment.setModel(model);
}
This is the Relevant portion of the stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: GUIPac.Stocktbl cannot be cast to [Ljava.lang.Object;
at GUIPac.ViewStockInfo.createChemicalsTableModel(ViewStockInfo.java:53)
at GUIPac.ViewStockInfo.<init>(ViewStockInfo.java:30)
The query "SELECT t FROM Stocktbl t WHERE t.chemical = FALSE" will return Stocktbl objects.
When iterating over the ResultList this causes ClassCastExceptions.
I would recommend to use this createQuery-Method:
TypedQuery<Stocktbl> query = FinancialDBPUEntityManager.createQuery("SELECT t FROM Stocktbl t WHERE t.chemical = FALSE", Stocktbl.class);
and then resolve all compiler warnings and errors.
If you need an Object Array, you will have to produce it manually, when using JPA. Here is a pseudo-code for creating these Object Arrays:
for(Stocktbl stock : results){// no error occurs here anymore.
Object[] obj = new Object[] {stock.ProductId, stock.ProductName, stock.NumberInStock, stock.numberNeedsReplacing};
data[index++] = obj;
}
please change field names of Stocktbl stock to fit to your Stocktbl class
The getResultList()- method get back a List of List<Stocktbl> not of Object[].
In runtime there is no generic. But when you iterate over it the cast fails.
Related
I have a native SQL query in Hibernate. I get the query result by :
List l = query.list().
I know that each element of the list corresponds to a line of the result table. But what are the types of those elements ?
Java tells me they are of type : Object. Ok but I want more. Because I want to print the results in the Eclipse console. But for that, I have to know the types, I have to know what this list exactly contains.
Here is the result table of my query I get in SL Developer :
And know, I want to print all that data in Eclipse console
In Eclipse, I use Query query = session.createSQlQuery("my query");
List l = query.list();`
For information, here is the SQL query code :
The Object in the list is an array of Objects (one per column).
You have to iterate (that's for each row) then use the array of columns:
final List<Object> l = query.list();
for (final Object row : l) {
final Object[] columns = (Object[]) row;
// use columns[0], columns[1] etc
System.out.println(columns[0]);
}
If I've got your issue correct, try getClass().getName() methods, which'll give you runtime class of your object. More info here
I want to read from database a pdf, which stores as BLOB and I want to get List<bytes[]>
session.beginTransaction();
final Criteria criteria = session.createCriteria(MyClass.class);
criteria.add(Restrictions.eq("id",id));
final ProjectionList projectionList = Projections.projectionList().add(
Projections.property("bdoc"));
criteria.setProjection(projectionList);
List<Object[]> list = criteria.list();
List<byte[]> listBytes = new ArrayList<byte[]>();
for (Object[] item : list) {
listBytes.add((byte[]) item[0]);
}
session.getTransaction().commit();
But I get an error in this line for (Object[] item : list) {
[ERROR] [B cannot be cast to [Ljava.lang.Object;
I've debugged and I do read data from database: my List<Object[]> list = criteria.list() is not empty.
But I can not convert from List<Object[]> to List<bytes[]>. What am I doing wrong? Help me please to resolve my problem.
B cannot be cast to [Ljava.lang.Object;
Means you are indeed getting bytearray and you are trying to convert it into Object array.
This problem is caused because Criteria.list() returns a raw List. As a result, you are able to write code that causes a ClassCastException. With a properly typed list, the compiler would prevent this.
As explained in the other answer, the text [B cannot be cast to [Ljava.lang.Object means that a byte[] is being cast to an Object[], which is not allowed.
This means that your list contains byte[] objects and you should declare it as such:
List<byte[]> list = criteria.list();
In addition, the contents of your for-loop now look incorrect:
listBytes.add((byte[]) item[0]);
Since item is now a byte[], it's not correct to cast a byte to a byte[]. Perhaps you need to remove the array index [0].
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());
}
java.lang.UnsupportedOperationException: This operation is not supported on Query Results
at org.datanucleus.store.query.AbstractQueryResult.contains(AbstractQueryResult.java:250)
at java.util.AbstractCollection.retainAll(AbstractCollection.java:369)
at namespace.MyServlet.doGet(MyServlet.java:101)
I'm attempting to take one list I retrieved from a datastore query, and keep only the results which are also in a list I retrieved from a list of keys. Both my lists are populated as expected, but I can't seem to user retainAll on either one of them.
// List<Data> listOne = new ArrayList(query.execute(theQuery));
// DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
// List<Data> listTwo = new ArrayList(ds.get(keys).values());
// listOne.retainAll(listTwo);
EDIT
Ok, in an attempt to simplify, since this is apparently multiple problems in one, I have stopped using the low level API for datastore and instead of am just pulling one by one with a loop.
List<MyClass> test = (List<MyClass>) query.execute();
List<MyClass> test2 = new ArrayList<MyClass>();
for (String key : favorites) {
test2.add(pm.getObjectById(MyClass.class, key));
}
log.info(test.toString());
test.retainAll(test2);
The above works. It doesn't throw the exception. The below does throw the exception. The only difference is the log.info. I'm stumped.
List<MyClass> test = (List<MyClass>) query.execute();
List<MyClass> test2 = new ArrayList<MyClass>();
for (String key : favorites) {
test2.add(pm.getObjectById(MyClass.class, key));
}
test.retainAll(test2);
It will not let me do new ArrayList() on the query result since it returns an array of objects.
You however need to put them in a new ArrayList(). The returned List implementation apparently doesn't support retainAll(). That's what the exception is telling you.
A "plain" ArrayList supports it. If passing through the ArrayList constructor is not possible due to difference in generic type, then you'll need to manually loop over it and cast each item before adding.
List<Data> listTwo = new ArrayList<Data>();
for (Object object : ds.get(keys).values()) {
listTwo.add((Data) object);
}
listOne.retainAll(listTwo);
Update: as per your update, the entities are apparently lazily loaded/filled. Most ORM's (DataNucleus is one) may indeed do that. As I don't use DataNucleus, I can't go in detail how to fix that in a "nice" way. But you at least now know the root cause of the problem and it can be solved the same way as above. Fill the list test in a loop as well.
If the type of collection you use for your "list of keys" does not support retainAll that exception will be thrown. Which type are you using?
TIP: you don't need to iterate to fill listTwo.
just do:
listTwo.addAll(ds.get(keys).values())
I want to insert CLOB value into my Oracle database and here is the what I could do. I got this exception while inserting operation "ORA-01461: can bind a LONG value only for insert into a LONG column". Would someone able to tell me what should I do? Thanks.
List<Object> listObjects = dao.selectAll("TABLE NAME", new XRowMapper());
String queryX = "INSERT INTO X (A,B,C,D,E,F) VALUES (?,?,?,?,?,XMLTYPE(?))";
OracleLobHandler lobHandler = new OracleLobHandler();
for(Object myObject : listObjects) {
dao.create(queryX, new Object[]{
((X)myObject).getA(),
((X)myObject).getB(),
new SqlLobValue (((X)myObject).getC(), lobHandler),
((X)myObject).getD(),
((X)myObject).getE(),
((X)myObject).getF()
},
new int[] {Types.VARCHAR,Types.VARCHAR,Types.CLOB,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR});
}
Are your parameters in the correct order? It's like the SQL statement has the LOB as the 6th parameter, but you're setting the LOB as the 3rd parameter.
Also, I assume getA() to getF() all return String values?
The first thing I'd do is eliminate either column C or F from your insert to determine which one is causing the error.