5

I have the simple code below:

@PersistenceContext(name = "mycontext")
private EntityManager entityManager;

public void getAggregatePower() {

    String sqlString = "SELECT SUM(power) FROM mytable";
    Object singleResult = entityManager.createNativeQuery(sqlString).getSingleResult();
    System.out.println(singleResult.getClass().getName());

}

When I run this in a real environment, the print instructions prints java.math.BigDecimal. But when I run this in my unit tests environment, the print instructions prints java.lang.Double.
In both cases I use a WildFly 9 server and a Postgresql 9.4 database. I also use Arquillian for unit tests. For me, the only noticeable difference is the number of records in database.
The power column in mytable table is a numeric(10,3).

I would like to avoid ugly code such as:

if (singleResult instance of Double) {
    ...
} else if (singleResult instance of BigDecimal) {
    ...
}

Is there a way to always have the same instance no matter my running environment ?

cheb1k4
  • 2,316
  • 7
  • 26
  • 39
  • You can use double precision in place of numeric for more detail see :http://www.postgresql.org/docs/9.4/static/datatype-numeric.html#DATATYPE-FLOAT – anand mishra Jan 14 '16 at 10:06
  • I don't think it's a good solution since it's indicated this: `If you require exact storage and calculations (such as for monetary amounts), use the numeric type instead.` – cheb1k4 Jan 14 '16 at 10:28
  • why use a native query on something that JPQL would support (assuming "mytable" has an Entity) ... – Neil Stockton Jan 14 '16 at 19:16
  • @NeilStockton because in reality my request is much more complicated than the one in my exemple. There are subqueries for instance. – cheb1k4 Jan 15 '16 at 10:51

2 Answers2

13

Both BigDecimal and Double extend Number, so you can do:

Number singleResult = ((Number) entityManager.createNativeQuery(sqlString).getSingleResult());
double resultAsDouble = singleResult.doubleValue();
BigDecimal resultAsBigDecimal = new BigDecimal(singleResult.toString()); 

Use resultAsDouble if you want the primitive type, but don't care about preserving the exact precision, use resultAsBigDecimal otherwise.

Adam Michalik
  • 9,678
  • 13
  • 71
  • 102
-1

You may do this

String sql = "SELECT SUM(power) FROM mytable";
Query q = em.createNativeQuery(sql);
BigDecimal result = (BigDecimal)q.getSingleResult();
Bikram
  • 828
  • 8
  • 21