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?
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());