Olá, sou iniciante no mundo Java e estou acompanhando as atividades "Java e JPA: Consultas avançadas, performance e modelos complexos" com o Rodrigo Ferreira.
Estou usando um banco real Postgres ao invés do H2 usado no curso. E, no momento, estou obtendo uma org.hibernate.query.sqm.sql.internal.InstantiationException ao executar uma instrução JPQL com um Select new e não estou encontrando respostas.
Pelo que entendi da exceção disparada, tem a ver com a Instanciação automática executada pelo Hibernate, dá a impressão de que ele não consegue instanciar o List que deve ser retornado pelo método que faz o select new. Segue a descrição do erro lançada no console:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.query.sqm.sql.internal.InstantiationException: Error performing dynamic instantiation : br.com.jpaexample.shop.vo.SalesReportVo
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:166)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:193)
at org.hibernate.query.spi.AbstractQuery.list(AbstractQuery.java:1373)
at org.hibernate.query.Query.getResultList(Query.java:131)
at br.com.jpaexample.shop.dao.CustomerOrderDao.getSalesReport(CustomerOrderDao.java:74)
at br.com.jpaexample.shop.tests.VoTest.main(VoTest.java:20)
Caused by: org.hibernate.query.sqm.sql.internal.InstantiationException: Error performing dynamic instantiation : br.com.jpaexample.shop.vo.SalesReportVo
at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationAssemblerConstructorImpl.assemble(DynamicInstantiationAssemblerConstructorImpl.java:58)
at org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:93)
at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:66)
at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:24)
at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:228)
at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:146)
at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:74)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:80)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:248)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:191)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:513)
at org.hibernate.query.spi.AbstractQuery.list(AbstractQuery.java:1364)
... 3 more
Segue o código da minha classe VO:
package br.com.jpaexample.shop.vo;
import java.time.LocalDate;
public class SalesReportVo {
private String productName;
private Long quantitySold;
private LocalDate lastSaleDate;
public SalesReportVo() {}
public SalesReportVo(String productName, Long quantitySold, LocalDate lastSaleDate) {
this.productName = productName;
this.quantitySold = quantitySold;
this.lastSaleDate = lastSaleDate;
}
/*Getters*/
@Override
public String toString() {
return "SalesReportVo [productName=" + productName + ", quantitySold=" + quantitySold + ", lastSaleDate="
+ lastSaleDate + "]";
}
}
Segue o código do método onde executo a instrução JPQL:
public List<SalesReportVo> getSalesReport() {
String jpql = "SELECT new br.com.jpaexample.shop.vo.SalesReportVo( "
+ "product.name, "
+ "SUM(item.quantity), "
+ "MAX(t_order.dateOrder)) "
+ "FROM CustomerOrder t_order "
+ "JOIN t_order.items item "
+ "JOIN item.product product "
+ "GROUP BY product.name, "
+ " item.quantity "
+ "ORDER BY item.quantity DESC ";
return em.createQuery(jpql, SalesReportVo.class)
.getResultList();
}
E por último a classe de teste do DAO e VO:
package br.com.jpaexample.shop.tests;
import java.util.List;
import javax.persistence.EntityManager;
import br.com.jpaexample.shop.dao.CustomerOrderDao;
import br.com.jpaexample.shop.util.JpaUtil;
import br.com.jpaexample.shop.vo.SalesReportVo;
public class VoTest {
public static void main(String[] args) {
EntityManager em = JpaUtil.getEntityManager();
CustomerOrderDao orderDao = new CustomerOrderDao(em);
em.getTransaction().begin();
List<SalesReportVo> reports = orderDao.getSalesReport();
reports.forEach(System.out::println);
em.close();
}
}
Alguma boa alma consegue dar aquele help esperto aí ?