ClassCastException when looping through the list populated using Hibernate query - java

I have a List ids populated by database query (Hibernate). The database
is PSQL. The ids column is bigint type.
Now the ids list is populated without any exception like this
List<Long> ids = getIds();//getIds returns List<Long>
but when I try to loop through the items on the ids list by
for (Long id : ids)
I get the exception
java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long
The value is 206131954. I don't know why it can add the value to the list, but later there is the error when trying to go through the list.
public List<Long> getIds() {
List<Long> externalIds = new ArrayList<Long>();
List<Person> persons = repository.getPeople();
for (Person person : persons) {
List<Long> ids = repository.getIdentifications(person);
if (ids.size() > 0) {
externalIds.addAll(ids);
}
}
return externalIds;
}
public List<Long> getIdentifications() {
String q = "select person_id from relevantpeople";
Query query = entityManager.createNativeQuery(q);
return (List<Long>) query.getResultList();
}

Use List<BigInteger> instead of List<Long>
BigInteger is capable of holding bigger integer numbers than Long.
BigInteger holds (2^32)^Integer.MAX_VALUE;
Long holds (2^63)-1;

Related

How to map Integer List from result

I am using java 7 and jdbc template to query a integer array from postgresql.My code is as below:
#Autowired
private JdbcTemplate jdbcTemp;
String SQL = "select item_list from public.items where item_id=1";
List<Integer> ListOfitems=jdbcTemp.queryForList(SQL , Integer.class);
My item_list column is integer[] in postgresql.But when I try like thid it throws an error as Bad value for type int psql exception.
Any help is appreciated
You can use java.sql.Array.
If you want to get only integer array you can try like this
String SQL = "select item_list from public.items where item_id=1";
Array l = template.queryForObject(SQL, Array.class);
List<Integer> list = Arrays.asList((Integer[]) l.getArray());
Or use RowMapper
Foo foo = template.queryForObject(SQL, new RowMapper<Foo>(){
#Override
public Foo mapRow(ResultSet rs, int rowNum) throws SQLException {
Foo foo = new Foo();
foo.setName(rs.getString("name"));
foo.setIntegers(Arrays.asList((Integer[]) rs.getArray("item_list").getArray()));
return foo;
}
});
Class Foo:
class Foo {
private String name;
private List<Integer> integers;
public String getName() {
return name;
}
// ...
}
queryForList saves each row that you got as a result from your query as an element of a List. It doesn't take the list that is saved into a column and returns it for you.
From the documentation : "The results will be mapped to a List (one entry for each row) of result objects, each of them matching the specified element type."
At best you will get a List<List<Integer>> returned, but I'm not sure fi you can use List<Interger>.class as a parameter for the call.

Unable to cast Object to Pojo class [duplicate]

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());
}

Difference bettween transformTuple and For loop on query Result - Hibernate

I have an HQL as select p,c from Person p,ContactCard c where c.fk_pid=p.id I executed this query as HQL using this code:
List<Person> personsWithContactCard = new ArrayList<Person>();
List<object[]> quryResult = new ArrayList<object[]>();
String qry = "select p,c from Person p,ContactCard c where c.fk_pid=p.id";
quryResult = session.createQuery(qry).list();
for(object[] obj : quryResult )
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
personsWithContactCard.add(person);
person=null;
}
By taking query result in list of object array and looping on query result I fill persons list.
But after reading about ResultTransformer Interface I come to know that with this interface I can transform queryResult in to desired list so I changed my code To :
String qry = "select p,c from Person p,ContactCard c where c.fk_pid=p.id";
personsWithContactCard = session.createQuery(qry).setResultTransformer(new ResultTransformer() {
#Override
public Object transformTuple(Object[] tuple, String[] aliases)
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
return person ;
}
#Override
public List transformList(List collection)
{
return collection;
}
}).list();
This code gives me persons list with for looping.
So my question is : What is the difference between transformTuple and For loop?
Does the both are same in performance and processing sense?
Which will be more good as per performance?
And what is the use of transformList()?
Update :
After understanding use of ResultTransformer as explained in answer given by #bellabax I did one small change in code as follows:
personsWithContactCard = session.createQuery(qry).setResultTransformer(new ResultTransformer() {
#Override
public Object transformTuple(Object[] tuple, String[] aliases)
{
Person person = new Person();
person = (Person)obj[0];
person.setContactCard = (ContactCard )obj[1];
return person ;
}
#Override
public List transformList(List collection)
{
return null;
}
}).list();
I changed transformList() method to return null if I execute this code I am getting null personsWithContactCard list. Why transformList() method is need to return collection when I am not using it? And when I supposed to use transformList() and transformTuple() means how I can decide which to use?
There aren't differences in terms of result usually, but using a ResultTransformer:
is the standard Hibernate method to process tuple and future (break) changes about how HQL is processed and tuple returned will be masked by a ResultTransformer without code changes
give you the possibilities to decorate or delegate (for example)
so the choice is the ResultTransformer.
About ResultTransformer.transformList():
Here we have an opportunity to perform transformation on the query
result as a whole
instead in transformTuple you can manipulate only one row of returned set.
EDIT:
As quoted above the javadoc of ResultTransformer.transformList() is pretty clear: this function allow to modify the whole list to remove duplicate, apply type conversion and so on and the result of ResultTransformer.transformList() is forwarded to Query.list() method so, return null from transformList whill return null from list().
This is how Query and ResultTransformer are tied.

sorting list of Object class before adding the list into the gridModel

The code is given below .........
private List<EmployeeAllRec> listg;
private List<Employee> list;
private List<Employee> gridModel;
private Map<String, String> json;
public String showAllRecord() {
records = 30;
rows = 10;
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
EmployeeAllRec rs = null;
try {
transaction = session.beginTransaction();
listg = new ArrayList();
List emp = session.createQuery("from Employee e").list();
int c=0;
//code for adding the data into the list
for (Iterator iterator = emp.iterator(); iterator.hasNext();) {
Employee e1 = (Employee) iterator.next();
System.out.println(e1.getName());
rs = new EmployeeAllRec();
rs.setName(e1.getName());
rs.setEmail(e1.getEmail());
rs.setDob(e1.getDob());
rs.setAddress(e1.getAddress());
rs.setGender(e1.getGender());
rs.setAge(e1.getAge());
rs.setCountry(e1.getCountry());
rs.setContact(e1.getContact());
rs.setWebsite(e1.getWebsite());
System.out.println("&&&&&&&&&&&&&&&&---i m on it " + rs.getName());
listg.add(rs);
}
setGridModel(listg);
// some stuff
My problem is that I need to sort the "listg" variable into descending order before adding it into the variable setGridModel....
Since the objects that are added into listg are taken from a DB, I would suggest ordering it through the HQL query.DB ordering is faster then in memory ordering (using a comparator), and in this case you can apply approach.
So the HQL query will look smth like "FROM Employee e ORDER BY... DESC"
Define a compareTo on your object that sorts them in descending order.
Call Collections.sort(listg) once it's populated.
PS: Consider using generics in your collections if possible.

Can Hibernate Custom query return a Map instead of a List?

Is it possible to return a map instead of a List from a custom JPA Query?
I know if is possible from the Entities themselves. In my case I have a custom query which returns some stats across different tables for a range of dates.
Ideally I would like the returned map to have the date as key and the stat as value.
You'll just have to create and populate the map by yourself:
List<Object[]> rows = query.list();
Map<Date, Integer> statsPerDate = new HashMap<Date, Integer>(rows.size());
for (Object[] row : rows) {
Date date = (Date) row[0];
Integer stat = (Integer) row[1];
statsPerDate.put(date, stat);
}

Categories

Resources