我们正在使用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(不是我的决定)。
答案 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的类型