J'implémente une requête qui renvoie la sortie dans un objet personnalisé. Avec mon implémentation, je reçois une erreur:
"method public abstract Java.util.List org.degs.repository.ConsolidateresponseRepository.transactions ()!"
Code de référentiel JPQL:
@Query(value = "SELECT new org.degs.beans.ConsolidateResDB(DATE_FORMAT(ts, '%d-%m-%Y') AS transdate,IFNULL(COUNT(orderreqid),0),IFNULL(COUNT(failamount),0),IFNULL(SUM(amount),0),IFNULL(SUM(successamount),0),IFNULL(SUM(failamount),0),IFNULL(COUNT(successcount),0)) FROM Consolidateresponse GROUP BY DATE_FORMAT(ts, '%d-%m-%Y') ORDER BY ts DESC")
public List<ConsolidateResDB> transactions();
ConsolidateResDB
haricot:
public class ConsolidateResDB {
String transdate;
long total;
long failcount;
double totalamount; double successamount;
double failamount;
long successcount;
}
J'ai déjà géré des valeurs NULL dans la requête elle-même et obtenir une sortie normale si j'exécute la même requête dans le terminal mysql db, mais lors de la mise en œuvre dans JPA et Spring Boot recevant toujours l'erreur NullPointerException
:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexController': Unsatisfied dependency expressed through field 'crRepo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consolidateresponseRepository': Invocation of init method failed; nested exception is Java.lang.IllegalArgumentException: Validation failed for query for method public abstract Java.util.List org.degs.repository.ConsolidateresponseRepository.transactions()!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:588) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.Java:88) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:366) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1264) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:553) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:483) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:306) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:761) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:866) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:542) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.degs.SbipgMisApplication.main(SbipgMisApplication.Java:16) [classes/:na]
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at Sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_121]
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_121]
at Java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_121]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.Java:49) [spring-boot-devtools-1.5.2.RELEASE.jar:1.5.2.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consolidateresponseRepository': Invocation of init method failed; nested exception is Java.lang.IllegalArgumentException: Validation failed for query for method public abstract Java.util.List org.degs.repository.ConsolidateresponseRepository.transactions()!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1628) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:555) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:483) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:306) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:202) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.Java:208) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.Java:1138) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.Java:1066) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:585) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 24 common frames omitted
Caused by: Java.lang.IllegalArgumentException: Validation failed for query for method public abstract Java.util.List org.degs.repository.ConsolidateresponseRepository.transactions()!
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.Java:92) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.Java:62) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.Java:72) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.Java:53) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.Java:144) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.Java:212) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.Java:77) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.Java:436) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.Java:221) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.Java:277) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.Java:263) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.Java:101) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1687) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1624) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 34 common frames omitted
Caused by: Java.lang.NullPointerException: null
at org.hibernate.hql.internal.NameGenerator.generateColumnNames(NameGenerator.Java:27) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.generateColumnNames(SessionFactoryHelper.Java:418) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.tree.SelectClause.initializeColumnNames(SelectClause.Java:267) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.tree.SelectClause.finishInitialization(SelectClause.Java:257) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.Java:252) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.Java:920) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.Java:688) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.Java:673) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.Java:309) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.Java:257) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.Java:262) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.Java:190) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.Java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.Java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.Java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.Java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.Java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.Java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.Java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.Java:291) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at Sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_121]
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_121]
at Java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_121]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.Java:347) ~[spring-orm-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.Sun.proxy.$Proxy85.createQuery(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.Java:86) ~[spring-data-jpa-1.11.1.RELEASE.jar:na]
... 47 common frames omitted
Vous avez dit à Spring de traiter cette requête comme une requête native. Sinon, il essaiera de le valider conformément à la spécification JPA.
Essayer:
@Query(value = "SELECT ...", nativeQuery = true)
public List<Object[]> transactions();
N'oubliez pas que dans ce cas, la syntaxe d'opérateur NEW ne peut pas être utilisée et que vous devez traiter le résultat sous la forme d'un tableau de Object
.
Alternativement
Si vous souhaitez utiliser les résultats directement sur une classe POJO, vous devez (en supposant que vous utilisez JPA 2.1+):
1) Définir le mappage:
@SqlResultSetMapping(
name="transactionsMapping",
classes={
@ConstructorResult(
targetClass=ConsolidateResDB.class,
columns={
@ColumnResult(name="transdate"),
@ColumnResult(name="orderreqid")
// further mappings ...
}
)
}
)
2) Définir une requête native
@NamedNativeQuery(name="transactions"
, query="SELECT DATE_FORMAT(ts, '%d-%m-%Y') AS transdate, IFNULL(COUNT(orderreqid),0) ... ")
) Définissez cette méthode dans le CrudRepository
sans le @Query
annotation:
public List<ConsolidateResDB> transactions();
Pour les données de printemps 2.0.5
et ci-dessus,
Après avoir essayé la solution de Maciej, mon code a commencé à se plaindre "Got different size of tuples and aliases".
Pour résoudre le problème dans la dernière version, nous devons ajouter
@Query(<Entity.FunctionName>, nativeQuery=true).
Cela a fait fonctionner mon code e2e.
J'ai fait face au même problème, ci-dessous a fonctionné pour moi.
@Query(value = "select NEW org.degs.beans.ConsolidateResDB(DATE_FORMAT(c.ts, '%d-%m-%Y') ,IFNULL(COUNT(c.orderreqid),0),IFNULL(COUNT(c.failamount),0),IFNULL(SUM(c.amount),0),IFNULL(SUM(c.successamount),0),IFNULL(SUM(c.failamount),0),IFNULL(COUNT(c.successcount),0)) FROM Consolidateresponse c GROUP BY DATE_FORMAT(c.ts, '%d-%m-%Y') ORDER BY c.ts DESC")
public List<ConsolidateResDB> transactions();