2

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

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

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

   // getters / setters
}

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

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

但是,我得到一个 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

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

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

4

4 回答 4

5

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

如果你有

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

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

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

例如

new BigDecimal("0.1")

比更精确

new BigDecimal(0.1d)

这篇文章解释了这一点

于 2012-10-05T09:00:22.277 回答
1

试试这个:

CAST(f.remaining AS big_decimal)

根据https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/queryhql.html:</p>

cast(... as ...),其中第二个参数是Hibernate 类型的名称,如果底层数据库支持 ANSI cast() 和 extract(),则为 extract(... from ...)

https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/type/package-summary.html

BigDecimalType big_decimal:将 SQL NUMERIC 映射到 java.math.BigDecimal 的类型

于 2020-06-15T04:38:07.477 回答
0
class named X  with a constructor that takes two parameters. The types of the parameters from the SELECT clause must match the signature defined in the class.

Syntax for the SELECT clause:

select_clause ::= SELECT [DISTINCT] select_expression
    {, select_expression}*
    select_expression ::=
    single_valued_path_expression |
    aggregate_expression |
    identification_variable |
    OBJECT(identification_variable) |
    constructor_expression
    constructor_expression ::=
    NEW constructor_name ( constructor_item {, constructor_item}* )
    constructor_item ::= single_valued_path_expression |
    aggregate_expression
    aggregate_expression ::=
    { AVG | MAX | MIN | SUM }
    ([DISTINCT] state_field_path_expression) |
    COUNT ([DISTINCT] identification_variable |
    state_field_path_expression |
    single_valued_association_path_expression)
于 2012-10-05T08:56:14.907 回答
0

为什么不使用 java.lang.Number 作为构造函数参数,并根据参数的 .floatValue() / doubleValue() 创建 BigDecimal 字段。

于 2012-10-05T18:59:23.457 回答