簡體   English   中英

JPA/Hibernate + HQL/JPQL:選擇帶有 BigDecimal 參數的 DTO

[英]JPA/Hibernate + HQL/JPQL: select DTO with BigDecimal parameter

我們使用帶有休眠的 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
}

我似乎無法進入休眠狀態以正確找到此構造函數。 我首先嘗試了以下查詢(模型比這更復雜,我最終需要獲取一些聚合(不是直接在實體上),這就是我獲取 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屬性在 Finances 實體上為 double 類型(不是我的決定)。

我不知道為什么 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 字符串構造器

例如

new BigDecimal("0.1")

new BigDecimal(0.1d)

這篇文章解釋了這一點

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)

為什么不使用 java.lang.Number 作為構造函數參數並根據參數的 .floatValue() / doubleValue() 創建 BigDecimal 字段。

試試這個:

CAST(f.remaining AS big_decimal)

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

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 的類型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM