javaspringhibernateentitymanager

How to pass a decimal value from a database into a DTO without getting a no matching constructor found error?


I've got a Java app that uses an EntityManager to query an Oracle database and populate a simple DTO class.

This works fine for varchars and strings - but throws an error:

Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection

as soon as I try to pass in a decimal value. I've tried making the type in the DTO a Double, double, and BigDecimal - but still get the error

Also - this used to work when it was running against Java 8. I had to upgrade to Java 17 and it started throwing the error.

@PersistenceContext
private EntityManager em;

String hql = "SELECT new my.example.MyDTO(mt.intVal as intVal, mt.decVal as decVal) " +
             "FROM MyTable mt " +
             "WHERE mt.id = 1234";

TypedQuery<MyDTO> findInsultsQuery = em.createQuery(hql, MyDTO.class);

//Here is where it gets the error - because of the mt.decVal
List<MyDTO> results = findInsultsQuery.getResultList();

Here is the DTO class. I've also tried the second parameter as a Double, double, Float, and float. It always throws the no matching constructor error.

public MyDTO(BigInteger intVal, BigDecimal decVal) {

}

Any suggestions?


Solution

  • I recommend to try from one of them.

    String hql = "SELECT new my.example.MyDTO(mt.intVal, cast(mt.decVal as BigDecimal)) " +
                 "FROM MyTable mt " +
                 "WHERE mt.id = 1234";
    
    List<Object[]> results = em.createQuery(
        "SELECT mt.intVal, mt.decVal FROM MyTable mt WHERE mt.id = 1234", Object[].class)
        .getResultList();
    
    List<MyDTO> dtoList = results.stream()
        .map(row -> new MyDTO(
            (BigInteger) row[0], 
            row[1] != null ? BigDecimal.valueOf(((Number) row[1]).doubleValue()) : null))
        .collect(Collectors.toList());