JPA/Hibernate + HQL/JPQL:选择带有 BigDecimal 参数的 DTO

Mor*_*sen 2 java hibernate jpa hql jpql

我们使用带有休眠的 JPA 作为实现。假设我有以下 DTO:

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

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

   // getters / setters
}
Run Code Online (Sandbox Code Playgroud)

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

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

但是,我得到了一个 org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class例外。

remaining我从中选择的列在 MSSQL 中存储为浮点数(我知道,我知道钱永远不应该存储为浮点数,但这是一个现有系统,我不能只更改此数据类型)。

作为测试,我尝试了以下查询,但有与上述相同的例外:

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

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

更新:remaining属性在 Finances 实体上为 double 类型(不是我的决定)。

RNJ*_*RNJ 5

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

如果你有

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

public SupplierInfoDto(String s, BigDecimal bd) {
   //set fields
}
Run Code Online (Sandbox Code Playgroud)

并不是说如果您使用 BigDecimal double 构造函数,则数字基于双精度数,因此仍然可能存在舍入错误。通常最好使用 BigDecimal 字符串构造器

例如

new BigDecimal("0.1")
Run Code Online (Sandbox Code Playgroud)

new BigDecimal(0.1d)
Run Code Online (Sandbox Code Playgroud)

这篇文章解释了这一点