I am converting stored procedure to complete JPA query. One of the SP query is as below which i am converting to entity class. I am converting this to a bean defined as Generic model which results in classcastexception.
SP query whose result set rs4 in java class is as follows:
rs4 Query: select command_value as descr from SCAN_COMMAND_NAME
where command_name = 'AAA' ORDER BY SEQ;
Here the result set rs4 is converted to GenericModel:
ResultSet rs4 = (ResultSet) cs.getObject(cnt++);
List commandRotateLi = new BeanProcessor().toBeanList(rs4,GenericModel.class);
session.setAttribute("coRotate", commandRotateLi);
///...
..///
ArrayList coRotate = (ArrayList) session.getAttribute("coRotate");
for(int x = 0; x < coRotate.size(); x++){
gm = (GenericModel) coRotate.get(x);
///
}
This above code works fine. Below is JPA converted code.
List<ScanCommandName> scanCommandList = new ArrayList<ScanCommandName>();
query = em.createNamedQuery("ScanCommandName.findByCommandName", ScanCommandName.class);
query.setParameter("commandName", Constants.IMAGE_MAGICK_ROTATE);
scanCommandList = query.getResultList();
scanCommandList.toString() gives me 5 ScanCommandName objects. I have to convert this List to List and loop through as above one but struck at class cast exception in the for loop.
ArrayList list = new ArrayList();
List<GenericModel> coRotate = null;
for(int y=0; y<scanCommandList.size(); y++){
ScanCommandName s = scanCommandList.get(y);
list.add(s.getCommandValue());
}
coRotate = (List<GenericModel>) (List) list;
I am now looping through the List coRotate but getting classcast at the 1st line in for loop.
for(int x = 0; x < coRotate.size(); x++){
gm = (GenericModel) coRotate.get(x);
///
}
java.lang.ClassCastException: java.lang.String cannot be cast to com.GenericModel
Any suggestions highly appreciated. thank you.
This is essentially what you are doing:
ArrayList list = new ArrayList();
List<SomeClass> slist;
list.add("String"); // <-- I'm guessing here based on exception
slist = (List<SomeClass>) list;
for (SomeClass s : slist) { // class cast exception
System.out.println(s);
}
class SomeClass {
}
Had you done this:
ArrayList<String> list = new ArrayList<>();
You could not have done this
slist = (List<SomeClass>) list;
And the error would have been caught at compile time.
Without knowing the details of your class structure, I suspect that to do what you want, coRotate needs to hold instances of GenericModel and
your ArrayList needs to be declared as ArrayList<GenericModel> = new ArrayList<>()
Related
I am getting the error in ClassCastException as below.
java.lang.ClassCastException: class java.util.HashMap$Values
cannot be cast to class java.util.Enumeration
(java.util.HashMap$Values and java.util.Enumeration are in module
java.base of loader 'bootstrap')
public static void addMemberships(final int key, MembershipData[] members) throws SpiderException
{
HashMap duplicates = new HashMap();
for (int i=0; i<members.length; i++)
{
if (duplicates.get(members[i].subjectOfCare) == null) {
duplicates.put(members[i].subjectOfCare, members[i]);
}
}
members = new MembershipData[duplicates.size()];
Enumeration elements = (Enumeration) duplicates.values(); //line where error occurs
for (int i=0; i<members.length; i++){
members[i] = (MembershipData) elements.nextElement();
}
internalMembershipToolkit.verifyData(key, members);
}
I tried using Enumeration elements = new IteratorEnumeration(duplicates.keySet().iterator()); but then I get another ClassCastException. Any advice on how to solve this?
Enumeration is an ancient interface that you should almost never need. It has been superseded by the Collection API, introduced in JDK 1.2, back-then in 1998.
When you use the capabilities of the Collection API, your entire code can be simplified to
public static void addMemberships(int key,MembershipData[] members) throws SpiderException
{
HashMap<Object, MembershipData> duplicates = new HashMap<>();
for(MembershipData m: members) duplicates.putIfAbsent(m.subjectOfCare, m);
members = duplicates.values().toArray(new MembershipData[0]);
internalMembershipToolkit.verifyData(key, members);
}
Note that assigning a new array to the parameter variable members does not alter the caller’s array. You could also pass the new array directly to the verifyData call, like
internalMembershipToolkit.verifyData(key,
duplicates.values().toArray(new MembershipData[0]));
More than often, you get even more advantages from the Collection API when eliminating the need to convert from and to an array. E.g. when you change the verifyData to accept a Collection<MembershipData> instead of MembershipData[], you can simply pass the duplicates.values() to the method, without the need to copy it into a new array.
Your problem is on the line:
Enumeration elements = (Enumeration) duplicates.values(); //line where error occurs
HashMap.values() returns a Collection, not an Enumeration. You can fix this like so:
Iterator elements = duplicates.values().iterator(); //line where error occurs
Do it as follows:
Collection<MembershipData> elements = duplicates.values();
Iterator<MembershipData> itr = elements.iterator();
for (int i = 0; i < members.length && itr.hasNext(); i++) {
members[i] = itr.next();
}
Please correct me if I am wrong, but you are trying to iterate over HashMap values and put it's values in an array.
This can be easily achieved using generics. Define your Map as:
Map<Integer,MembershipData> duplicates = new HashMap<Integer,MembershipData>();
And then iterating it over like
i=0;
for(MembershipData data:dupliates.values()){
members[i++] = data;
}
Getting the following error in Android Studio:
Getting:
java.lang.ArrayStoreException: source[0] of type com.example.glide.ImageList cannot be stored in destination array of type java.lang.String[] in this line
Code:
ArrayList<ImageList> list = new ArrayList<>();
Object[] objNames = list.toArray();
String[] strNames = Arrays.copyOf(objNames, objNames.length, String[].class);
for(int j=0; j < strNames.length; j++){
strNames[j] = String.valueOf(list.get(j));
Log.d("String : {} ", strNames[i]);
}
Your program has lots of logical mistakes.
But try this one
public static void main(String[] args) {
ArrayList<ImageList> list = new ArrayList<>();
list.add(new ImageList()); //adding some dummy objects, you add yours
list.add(new ImageList());
String[] strNames = new String[list.size()];
for(int j=0; j < strNames.length; j++){
strNames[j] = String.valueOf(list.get(j));
Log.d("String : {} ", strNames[i]);
}
}
First, you have a list of ImageList items.
Second, this list is empty.
Third, you have defined an Array of String , and use Array.copyOf to populate it.
This won't work. You can cast ImageList to String directly.
What is that you are trying to achieve here?
Not sure, if you want a string representation of ImageList you can iterate over your "list" and call the .toString() method on each instance so you get the string representation of your instance.
Again not clear what you want?
java.util.List records = new java.util.ArrayList();
java.sql.ResultSet rs = selectestatement.executeQuery(query1);
while (rs.next()) {
java.util.List record = new java.util.ArrayList();
record.add(rs.getString("WHLO").trim());
record.add("888509018579");
record.add(rs.getString("ITEM_CODE").trim());
record.add(rs.getString("ARRIVAL_DATE").trim());
record.add(rs.getString("PAIRS_PER_CASE").trim());
record.add(rs.getString("ATS").trim());
records.add(record);
}
In this code, Final arraylist is the "records array". This records arraylist contents few record arrays.
How can i access the 1st element of record arraylist from the records arraylist?
Don't use raw types:
List<List<String>> records = new ArrayList<>();
List<String> record = new ArrayList<>();
...
records.add(record);
This way records.get(i) will return a List<String> instead of an Object, so you can access the elements of the inner List:
String first = records.get(0).get(0);
What you really want is a class containing your row data.
class RecordData {
public String whlo;
public long someNumber = 888509018579;
public String itemCode;
public String arrivalDate;
public String pairsPerCase;
public String ats;
}
and then do
java.util.List<RecordData> records = new java.util.ArrayList<>();
while (rs.next()) {
RecordData record = new RecordData();
record.whlo = rs.getString("WHLO").trim();
record.itemCode = rs.getString("ITEM_CODE").trim();
record.arrivalDate = rs.getString("ARRIVAL_DATE").trim();
record.pairsPerCase = rs.getString("PAIRS_PER_CASE").trim();
record.ats = rs.getString("ATS").trim();
records.add(record);
}
In fact, you want to make the members private and accessible via getters and setters, and use LocalDate for the arrivalDate and int for the pairsPerCase member, but the first point is not using a List to store the retrieved values but wrap it in a business-oriented class.
You can do something like this
((ArrayList)records.get(0)).get(0) to access the first element of the array list that is in the first position of the records array list.
Please note that if you specify what does the records contains (in this case records will contains array lists) then you won't need to cast the element to array list.
List<List<String>> records = new ArrayList<ArrayList>();
{...}
records.get(0).get(0); //You don't need the cast because Java already knows that what it is inside records are Lists
I am trying to build a string to pass it as an SQL query within the IN statement.
ArrayList<Object[]> arrayList = new ArrayList<Object[]>();
List<String> strings = new ArrayList<>(arrayList .size());
for (Object object : arrayList ) {
strings.add(Objects.toString(object, null));
}
System.out.println("askldnlkasdn"+strings);
This still prints out the memory locations instead of the actual string
askldnlkasdn[[Ljava.lang.Object;#7bb11784, [Ljava.lang.Object;#33a10788, [Ljava.lang.Object;#7006c658, [Ljava.lang.Object;#34033bd0, [Ljava.lang.Object;#47fd17e3, [Ljava.lang.Object;#7cdbc5d3, [Ljava.lang.Object;#3aa9e816, [Ljava.lang.Object;#17d99928, [Ljava.lang.Object;#3834d63f, [Ljava.lang.Object;#1ae369b7]
I have also tried out
using StringBuilder and StringUtils. But things dont seem to work.
Any inputs as to where the problem is?
you should override method toString in your objects
You can use an SQL specific java Array.
try (PreparedStatement stmt = connection.prepareStatement("... IN (?) ...")) {
Object[] elements = ...
stmt.setArray(1, connection.createArray("TEXT", elements));
stmt.executeUpdate();
}
The problem you have is that you are implicitly using the toString() method of the Object elements inside your ArrayList. By default, that method returns the class and address of the Object. You should override the toString() method in every class you will use inside the list so it returns what you want it to.
This is new code that may help,
// Data of Array of Object for test the Code
Object[] a = new Object[1];
a[0] = "Hello";
Object[] b = new Object[1];
b[0] = "Friend";
Object[] c = new Object[1];
c[0] = "This is";
Object[] d = new Object[1];
d[0] = "Just Test";
// The Array List of objects and the data entry
ArrayList<Object[]> arrayList = new ArrayList<Object[]>();
arrayList.add(a);
arrayList.add(b);
arrayList.add(c);
arrayList.add(d);
// New List of strings
List<String> strings = new ArrayList<>(arrayList .size());
// The Process of adding the data from array list of objects to the strings
for(int i = 0; i < arrayList.size(); i++){
strings.add((String) arrayList.get(i)[0]);
}
// Just for print the data to console
for(int i = 0 ; i < strings.size(); i++){
System.out.println(strings.get(i));
}
System.out.println("askldnlkasdn "+strings.get(0));
I hope that solve the problem, if not please inform me, you can use it for more than one dimensional array.
You can just save it as String , like this code
ArrayList<String> arrayList = new ArrayList<>();
List<String> strings = new ArrayList<>(arrayList .size());
for (Object object : arrayList ) {
strings.add(Objects.toString(object, null));
}
System.out.println("askldnlkasdn"+strings);
Or you want it Object for specific purpose?
I have a resultList which fetches result from a JPQL query that queries multiple tables as described :
Query query = em.createQuery("SELECT protein.gid,protein.uniProtAccession,protein.name,protein.ECNumber,ttdtarget.uniProtID,ttdtarget.gid FROM Protein protein,TtdTarget ttdtarget WHERE protein.uniProtAccession = ttdtarget.uniProtID");
List resultList = query.getResultList();
Note: I am restricting the size of resultset to 5 right now, just for debugging. I want to get the values returned inside each object from the resultList, which basically is an array of objects.
So far I have tried iterating upto the objects but can't access the inner values.
for (int i = 0; i < resultList.size(); i++)
{
System.out.println("->"+resultList.get(i));
}
Output:
->[Ljava.lang.Object;#141ab9e
->[Ljava.lang.Object;#6a15ca
->[Ljava.lang.Object;#bcb654
->[Ljava.lang.Object;#1664b54
->[Ljava.lang.Object;#db953c
And here is the variable's output from debug:
So my question is how to access those values inside the object.
The result is List<Object[]>, so cast to that. So a list, where each element is an array of values. You must then cast each value to its type (which you know beforehand).
If you simply want to iterate and print:
List<Object[]> resultList = (List<Object[]>) query.getResultList();
for (Object[] array : resultList) {
for (Object field : array) {
System.out.println("->"+field);
}
}
Alternatively, you can create a new class which has these exact fields, make its constructor accept all of the values, and use it in the query: SELECT new Foo(.....) FROM... There you can use the generic alternative of em.createQuery(..) that returns TypedQuery
You don't have a List of Objects, it is a List of Objectarrys
List<Object[]> resultList = (List<Object[])resultList;
for (int i = 0; i < resultList.size(); i++)
{
System.out.print("protein.gid ->"+resultList.get(i)[0]);
System.out.println("protein.uniProtAccession ->"+resultList.get(i)[1]);
}
List<Object[]> resultList = query.getResultList();
for (Object[] objects : resultList)
{
for (Object object : objects)
{
System.out.println(object)
}
}
Your result form the query is array of objects.
List resultList = query.getResultList();
for(Object result : resultList) {
Object[] results = (Object[]) result;
for(Object res : results) {
System.out.println(res);
}
}
Or you can go with Bozho solution and create new direct from query.
You can create a new class with the exact fields you need and use a TypedQuery
TypedQuery<CustomClass> query = em.createQuery("" /* Query String */, CustomClass.class);
List<CustomClass> resultList = query.getResultList();
foreach (CustomClass result : resultList){
// Need to override method toString() in CustomClass
System.out.println("->" + result);
}
I'm tempted to suggest nesting a for loop:
for (int i = 0; i < resultList.size(); i++)
{
for(int j = 0; j < resutList.get(i).size(); j++){
System.out.println("->"+resultList.get(i).get(j));
}
}