issue while converting BigDecimal to Integer - java

I'm facing problem while converting Big Decimal to Integer.
My process description is, First I will be sending List of Integers into a DAO method to validate whether the integers are valid to proceed further. Then the valid List of Integers are processed in another place.
Core process
List<Integer> payments = DAO.checkStatus(payments); //payments is List of Integer
if(payments!=null){
//Do some other operation
DAO.changeStatus(payments); //Here payments is List of Integer which we got from above
DAO method implementation
checkStatus(List<Integer> payments){
List<Integer> FinalPayments = null;
//I have Hibernate query to get the details from Database
String HQL_Query = "select A.PY from T_Status A where A.status = 4 and (A.PY=:payments)";
Query query = session.CreateQuery(HQL_Query);
FinalPayments = query.list();
return FinalPayments;
}
In the DataBase PY column is a BigDecimal one. In table its defined as NUMBER. type. While execution of the query i'm getting BigDecimal values for FinalPayments list. There was no error/exception. The BigDecimal value is returned properly.
In core process, after the 1st method:
if(payments!=null){
//we're doing something with List of Integer payments right?
//It is passed to 2nd method.
changeStatus(List<Integer> FinalPayments){
String HQL_Query="update T_Status A set A.status = 6 where (A.PY:=FinalPayments)";
Query query = session.CreateQuery(HQL_Query);
query.setParameter("FinalPayments", FinalPayments); //Here i'm getting error
List<Integer> paymentsAfter = query.list();
}
The error is:
cannot cast java.math.BigDecimal to java.lang.Integer
Between 1st and 2nd method i tried to convert BigDecimal to Integer. But can't convert Integer list to Integer again.But i need those to be in the format of Integer to process 2nd method. Please help on this..

Use the intValue() method on your BigDecimal object to get its int value.

I'm not sure I understand your question but if you have a BigDecimal and you want a Integer you can use either intValue of intValueExact.
E.g.
List<BigDecimal> decimals = ...
List<Integer> ints = decimals.stream().map(BigDecimal::intValue).collect(Collectors.toList());

Related

why the element in my List<Integer> is type Character?

As shown in above picture, my method accepts `List includedDays, and I expect the element is of type Integer, but why in debug mode, I find that the element is of typeCharacter?
includeDays comes from the following code:
List<Integer> includedDays = getDowByTrmClassId(trmClassId);
and getDowByTrmClassId(trmClassId) is defined as:
List<Integer> getDowByTrmClassId(Integer trmClassId){
Session session = HibernateUtil.getCurrentSession();
String sql = " select DOW from TRM_CLASS_DOW cdow " +
"where (cdow.UPDATE_MODE is null or cdow.UPDATE_MODE <> 'D') " +
" AND cdow.TRM_CLASS_ID = :trmClassId " +
" ORDER BY cdow.dow";
Query sqlQuery = session.createSQLQuery(sql);
sqlQuery.setParameter("trmClassId", trmClassId);
List<Integer> classDows = sqlQuery.list();
return classDows;
}
the column dow is of type varchar(1)
I think this is the culprit on your problem.
the column dow is of type varchar(1)
Varchar should return a String result for this field. But I found that hibernate has some issue on this, when varchar contain single character, the result will be converted to char/Character datatype in your Java. Look at these issues, HHH-2220, HHH-2304 and other with the same problem. It pointed out here, and I quote
Currently Hibernate supports a kind of "automagic" mapping from SQL types to Hibernate/Java types - because of the many ambiguities in doing such mapping it will sometime not match what you actually want.
Suggestion:
Since you really expect a Character because of the above code and the issue, you should fix the datatype issue on your database and Java. You can permanently convert you database to correct datatype (Integer if it really range from 0-9). Or if you can't do database modification, you can do it by creating helper class/method to manually parse each result to Integer like using a method something like:
/**
* You parser method of Character to Integer
*/
public List<Integer> converToIngeter(List resultList){//This should accept your resultSet from your query as List
List<Integer> toReturn = new ArrayList<>();
resultList.stream().forEach((o)->{
if(Character.isDigit((Character) o)){//(Character) o) is just an insurance that the instance is Character
toReturn.add(Character.getNumericValue((Character)o));
}
});
/* Or you do some other parsing
*/
return toReturn;
}
In your code
List<Integer> getDowByTrmClassId(Integer trmClassId){
. . . //Your other code here
sqlQuery.setParameter("trmClassId", trmClassId);
List<Integer> classDows = converToIngeter(sqlQuery.list()); //converToIngeter(list) was added to convert the result to Integer
return classDows;
}
You can look other char to integer parsing like here on the internet.
Or To fix datatype problem of Varchar being returned as Character on Java, This answer suggested to add .addScalar("PREFIX", Hibernate.STRING); on your query. Eg.
sqlQuery.setParameter("trmClassId", trmClassId);
sqlQuery.addScalar("PREFIX", Hibernate.STRING);
Then, parse them to Integer later on.
===============
UPDATE:
Remove unrelated answer. Thanks you Andreas for pointing out some that I have neglected.

How to use Sum SQL with Spring Data MongoDB?

I want to sum the values of a column price.value where the column validatedAt is between startDate and endDate.
So I want a BigInteger as a result (the sum value).
This is what I tried:
final List<AggregationOperation> aggregationOperations = new ArrayList<>();
aggregationOperations.add(Aggregation.match(where("validatedAt").gte(startDate).lt(endDate)));
aggregationOperations.add(Aggregation.group().sum("price.value").as("total"));
final Aggregation turnoverAggregation = Aggregation.newAggregation(OrderEntity.class, aggregationOperations);
return this.mongoOperations.aggregate(turnoverAggregation, OrderEntity.class, BigInteger.class).getUniqueMappedResult();
This doesn't work. I have this error:
{"exception":"com.application.CommonClient$Builder$6","path":"/api/stats/dashboard","message":"Failed to instantiate java.math.BigInteger using constructor NO_CONSTRUCTOR with arguments ","error":"Internal Server Error","timestamp":1493209463953,"status":500}
Any help?
You don`t need to add a new pojo for just for this. It is helpful when you more fields to map and you want spring to map them automatically.
The correct way to fix the problem is to use BasicDBObject because MongoDB stores all values as key value pairs.
return this.mongoOperations.aggregate(turnoverAggregation, OrderEntity.class, BasicDBObject.class).getUniqueMappedResult().getInt("total");
Sidenote: You should use Double/BigDecimal for monetary values.
I resolved this problem by creating a class that has a BigInteger attribute:
private class Total {
private int total;
}
return this.mongoOperations.aggregate(turnoverAggregation, OrderEntity.class, Total.class).getUniqueMappedResult();

How to get an integer value using hibernate createSQLQuery?

I need to fetch the result of the following query but i am getting a typecast exception. Kindly help out!
SELECT COUNT(*) FROM ( SELECT DISTINCT a.PROPSTAT_CODE,a.PROPSTAT_DESC,a.PROPSTAT_TYPE FROM CNFGTR_PROPSTAT_MSTR a WHERE 1 = 1 )
My code is given below,
Query query = session.createSQLQuery(sqlQuery);
listRes = query.list();
int ans = ((Integer)listRes.get(0)).intValue();
Thanks in advance
Since you say that you are wrapping the above query in another query that returns the count, then this will give you want, without having to convert to any other data types.
Integer count = (Integer) session.createSQLQuery("select count(*) as num_results from (SELECT DISTINCT a.PROPSTAT_CODE,a.PROPSTAT_DESC,a.PROPSTAT_TYPE FROM CNFGTR_PROPSTAT_MSTR a WHERE 1 = 1)")
.addScalar("num_results", new IntegerType())
.uniqueResult();
System.err.println(count);
The trick is the call to "addScalar". This tells Hibernate you want the data type of "num_results" pre-converted to an Integer, regardless of what your specific DB implementation or JDBC driver prefers. Without this, Hibernate will use the type preferred by the JDBC driver, which explains why different answers here have different casts. Setting the desired result type specifically removes all guesswork about your returned data type, gives you the correct results, and has the added bonus of being more portable, should you ever wish to run your application against a different relational database. If you make the call to "list" instead of "uniqueResult" then you can assign the results directly to a List
Use long instead of int. Hibernate returns count(*) as long not int.
Query query = session.createSQLQuery(sqlQuery);
listRes = query.list();
long ans = (long)listRes.get(0);
Well.. I suppose this should work:
Query query = session.createSQLQuery(sqlQuery);
List listRes = query.list();
int ans = ((BigDecimal) listRes.get(0)).intValue();
Note: you need to import java.math.BigDecimal
List number=session.createSQLQuery("SELECT COUNT(*) FROM devicemaster WHERE ClientId="+id).list();
session.getTransaction().commit();
int ans = ((java.math.BigInteger) number.get(0)).intValue();

Parsing an object attribute type to a different type?

I have 2 collections: product and inventory. I am trying to enter new inventory for a store.
when I'm filling out inventory entry form I want the product number I enter to search the product list to resolve the correct name of the item.
I have a search method in my product collection but it takes an integer type. The product number is of type long.
How can I convert the product number to an integer so the search will function correctly?
//resolve product name to inventory item
int idx = prodL.search(Integer.parseInt(prodNo));
name = prodL.getProdName(idx);
Error: The method parseInt(java.lang.String) in the type java.lang.Integer is not applicable for the arguments (long)
Try this:
int idx = prodL.search((int)prodNo);
Please note this will truncate, so if prodno exceed Integer.MAX_VALUE, you will get some odd results.
You could wrap it in an Integer type and use Integer.longValue()

How to get attributes of an Object in Java?

I have a function that returns an Object
The toString() method shows that my object has two BigDecimal attributes. But I don't know how to get them in the code ?
My function uses hibernate to get results from a query is :
public Object executeQuery(final String sql) {
final Query query = getSessionFactory().getCurrentSession().createSQLQuery(sql);
return query.list().get(0);
}
Thank you.
-- Additional infos:
obj.getClass().getDeclaredFields(); // empty array []
obj.getClass().getName(); // [Ljava.lang.Object;
final BigDecimal b = (BigDecimal) obj[0]; //Compilation error: The type of the expression must be an array type but it resolved to Object
obj.getClass().getDeclaredFields() can help you. Generally learn reflection API. If you object bean you can also use Jackarta BeanUtils.
Judging from your comments, your Object is and Object array.
So you should first cast the result to an Object array:
Object[] obj = (Object[]) query.list().get(0);
Then, you should be able to access the first BigDecimal like that:
BigDecimal b = (BigDecimal) obj[0];
Probably, you want to add some exception handling.
It is not an Object, it is an Array of Objects.
BigDecimal firstColumn = (BigDecimal) ((Object[])query.list().get(0))[0];
BigDecimal secondColumn = (BigDecimal) ((Object[])query.list().get(0))[1];
That's all.
UPDATE:
You have a resultset with 2 columns.
Object[] result= query.list().get(0);
BigDecimal number1 = (BigDecimal) result[0];
BigDecimal number2 = (BigDecimal) result[1];
Get first what class name of that object by
System.out.println(obj.getClass());
Since you are running a sql query, result might be an Entity or Object[].
when you came to know retrieved object from query is an Object[] you can iterate like
if( obj instanceof Object[] ) {
Object[] objA = (Object[])obj;
for(Object atomicObj : objA ) {
System.out.println(atomicObj);
}
}
It works for all elements which presents in object array. This time you may get BigDecimal, next query might return a String and BigDecimal.

Categories