JPA / Hibernate + HQL / JPQL:使用BigDecimal参数选择DTO

时间:2012-10-05 08:24:30

标签: java hibernate jpa hql jpql

我们正在使用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
}

我似乎无法让hibernate正确地找到这个构造函数。我首先尝试了以下查询(模型比这更复杂,我需要最终获取一些聚合(不直接在实体上),这就是为什么我提取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 个答案:

答案 0 :(得分:3)

我不确定为什么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 string contstrctor

例如

new BigDecimal("0.1")

更精确
new BigDecimal(0.1d)

This文章解释了这个

答案 1 :(得分: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)

答案 2 :(得分:0)

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

答案 3 :(得分:0)

尝试一下:

CAST(f.remaining AS big_decimal)

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

cast(... as ...),其中第二个参数是 休眠类型 的名称,然后提取(... from ... ),如果基础数据库支持ANSI cast()和extract()

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

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