JPA / Hibernate + HQL / JPQL:使用BigDecimal参数选择DTO [英] JPA/Hibernate + HQL/JPQL: select DTO with BigDecimal parameter

查看:800
本文介绍了JPA / Hibernate + HQL / JPQL:使用BigDecimal参数选择DTO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用JPA和hibernate作为实现。假设我有以下DTO:

  public class SupplierInfoDto {
private String supplierName;
私人BigDecimal remainingFinances;

public SupplierInfoDto(String supplierName,BigDecimal remainingFinances){
this.supplierName = supplierName;
this.remainingFinances = remainingFinances;
}

// getters / setters
}



<我似乎无法得到休眠正确找到这个构造函数。我首先尝试了以下查询(模型比这更复杂,我最终需要获取一些聚合(不直接在实体上),这就是为什么我要获取DTO而不是实体):

 选择新的com.company.dto.SupplierInfoDto(s.name,f.remaining)
FROM供应商的INNER JOIN财务f
WHERE s.id =:SupplierId

然而,我得到了一个 org .hibernate.hql.ast.QuerySyntaxException:无法找到类异常的相应构造函数。

我选择的剩余的列在MSSQL中存储为一个浮点数(我知道,我知道钱不应该作为浮点数存储,但这是一个现有的系统,我不能只是改变这种数据类型)。

作为一个测试,我尝试了下面的查询,但是与上面相同的异常:

  SELECT new com.company.dto.SupplierInfoDto(s.name,NEW java.math.BigDecimal (10))
FROM供应商s
其中s.id =:SupplierId

所以我的问题是:我如何让hibernate / JPA为上述两个查询找到合适的构造函数?


$ b

更新: remaining 属性在财务实体中是double类型的(不是我的决定)。

解决方案

我不确定为什么BigDecimal ctor没有被识别,但是你可以重载你的构造函数



如果你有

 公共SupplierInf oDto(String s,Double d){
this(s,new BigDecimal(String.valueOf(d)));
}

public SupplierInfoDto(String s,BigDecimal bd){
// set fields
}

不是,如果使用BigDecimal双构造函数,则数字基于double,所以仍然可能有舍入错误。通常最好使用BigDecimal字符串contstrctor



例如

 新的BigDecimal(0.1)


$ b更精确$ b

  new BigDecimal(0.1d)

< a href =http://rayfd.me/2007/04/26/the-evil-bigdecimal-constructor/ =nofollow>这篇文章解释了这个问题


We are using JPA with hibernate as the implementation. Suppose I have the following DTO:

public class SupplierInfoDto{
   private String supplierName;
   private BigDecimal remainingFinances;

   public SupplierInfoDto(String supplierName, BigDecimal remainingFinances){
       this.supplierName = supplierName;
       this.remainingFinances = remainingFinances;
   }

   // getters / setters
}

I cannot seem to get hibernate to properly find this constructor. I first tried the following query (the model is more complicated than this, and I need to fetch some aggregations eventually (not directly on the entities), that's why I'm fetching a DTO instead of the entities):

SELECT NEW com.company.dto.SupplierInfoDto(s.name, f.remaining)
FROM Supplier s INNER JOIN Finances f
WHERE s.id = :SupplierId

However, I get a org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class exception.

The remaining column I'm selecting from is stored as a float in MSSQL (I know, I know money should never be stored as floats, but this is an existing system where I cannot just change this datatype)..

As a test, I tried the following query, but with the same exception as above:

SELECT NEW com.company.dto.SupplierInfoDto(s.name, NEW java.math.BigDecimal(10))
FROM Supplier s
WHERE s.id = :SupplierId

So my question is: How do I make hibernate/JPA find the appropriate constructor for the two queries above?

UPDATE: The remaining property is of type double on the Finances entity (not my decision).

解决方案

I am not sure why the BigDecimal ctor is not being recognised but you could overload your constructors

If you had

public SupplierInfoDto(String s, Double d) {
   this(s, new BigDecimal(String.valueOf(d)));
}

public SupplierInfoDto(String s, BigDecimal bd) {
   //set fields
}

Not that if you use the BigDecimal double constructor the number is based on a double so can still have rounding errors. It is usually best to use BigDecimal string contstrctor

For example

new BigDecimal("0.1")

is more precise than

new BigDecimal(0.1d)

This article explains this

这篇关于JPA / Hibernate + HQL / JPQL:使用BigDecimal参数选择DTO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆