【问题标题】:JPA native query returns Double or BigDecimalJPA 本机查询返回 Double 或 BigDecimal
【发布时间】:2016-04-19 13:49:23
【问题描述】:

我有下面的简单代码:

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

}

当我在真实环境中运行它时,打印指令会打印出java.math.BigDecimal。但是当我在我的单元测试环境中运行它时,打印指令会打印出java.lang.Double
在这两种情况下,我都使用 WildFly 9 服务器和 Postgresql 9.4 数据库。我也使用 Arquillian 进行单元测试。对我来说,唯一明显的区别是数据库中的记录数。
mytable 表中的power 列是numeric(10,3)

我想避免丑陋的代码,例如:

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

无论我的运行环境如何,有没有办法始终拥有相同的实例?

【问题讨论】:

  • 您可以使用双精度代替数字以获取更多详细信息,请参阅:postgresql.org/docs/9.4/static/…
  • 我认为这不是一个好的解决方案,因为它表明了这一点:If you require exact storage and calculations (such as for monetary amounts), use the numeric type instead.
  • 为什么对 JPQL 支持的东西使用原生查询(假设“mytable”有一个实体)...
  • @NeilStockton 因为实际上我的请求比我的示例中的请求复杂得多。例如有子查询。

标签: java postgresql jpa wildfly-9


【解决方案1】:

BigDecimalDouble 都扩展 Number,所以你可以这样做:

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

如果您想要原始类型,请使用resultAsDouble,但不关心保持精确的精度,否则使用resultAsBigDecimal

【讨论】:

  • 也许是最好的解决方法。我会尽快尝试的。
  • 我认为这是迄今为止最安全的解决方案。
【解决方案2】:

你可以这样做

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2016-11-02
    • 2012-10-09
    • 1970-01-01
    相关资源
    最近更新 更多