We are using JPA with hibernate as the implementation. Suppose I have the following DTO:
public class SupplierInfoDto{
private String supplierName;
private BigDecimal remainingFinances;
public SupplierInfoDto(String supplierName, BigDecimal remainingFinances){
this.supplierName = supplierName;
this.remainingFinances = remainingFinances;
}
// getters / setters
}
I cannot seem to get hibernate to properly find this constructor. I first tried the following query (the model is more complicated than this, and I need to fetch some aggregations eventually (not directly on the entities), that's why I'm fetching a DTO instead of the entities):
SELECT NEW com.company.dto.SupplierInfoDto(s.name, f.remaining)
FROM Supplier s INNER JOIN Finances f
WHERE s.id = :SupplierId
However, I get a org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class
exception.
The remaining
column I'm selecting from is stored as a float in MSSQL (I know, I know money should never be stored as floats, but this is an existing system where I cannot just change this datatype)..
As a test, I tried the following query, but with the same exception as above:
SELECT NEW com.company.dto.SupplierInfoDto(s.name, NEW java.math.BigDecimal(10))
FROM Supplier s
WHERE s.id = :SupplierId
So my question is: How do I make hibernate/JPA find the appropriate constructor for the two queries above?
UPDATE: The remaining
property is of type double on the Finances entity (not my decision).
I am not sure why the BigDecimal ctor is not being recognised but you could overload your constructors
If you had
public SupplierInfoDto(String s, Double d) {
this(s, new BigDecimal(String.valueOf(d)));
}
public SupplierInfoDto(String s, BigDecimal bd) {
//set fields
}
Not that if you use the BigDecimal double constructor the number is based on a double so can still have rounding errors. It is usually best to use BigDecimal string contstrctor
For example
new BigDecimal("0.1")
is more precise than
new BigDecimal(0.1d)
This article explains this