1

The JPA repository has the following method which was working fine before but now it throws a strange error. The jpa is defined as:

@Repository
public interface UserGroupRepository extends JpaRepository<UserGroup, Long> {
...

and the method is below:

    String USER_GROUP_SUMMARY = "SELECT b.name, b.id, count(u.user_id) as total_user,\n" +
            "           sum(case u.is_active when true then 1 else 0 end) as active_user\n" +
            "           FROM user_group b\n" +
            "                      LEFT JOIN user u\n" +
            "                         ON u.group_id = b.id\n" +
            "                      GROUP BY b.name, b.id\n" +
            "                      order by b.name ASC;";
    @Query(value = USER_GROUP_SUMMARY, nativeQuery = true)
    List<Map<String,Object>> getAllGroupSummary();

the query return the follow result however: enter image description here

an abstract from pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <freemarker.version>2.3.28</freemarker.version>
        <spring.boot.version>2.1.6.RELEASE</spring.boot.version>
    </properties>
...

Now it throws the error stack trace is below:

2020-03-06 19:14:13.720 ERROR 2892 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IndexOutOfBoundsException: Index: 1, Size: 1] with root cause

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:657) ~[na:1.8.0_181]
    at java.util.ArrayList.get(ArrayList.java:433) ~[na:1.8.0_181]
    at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.toMap(ResultProcessor.java:315) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.getProjectionTarget(ResultProcessor.java:303) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:290) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:213) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:152) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:141) ~[spring-data-jpa-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125) ~[spring-data-jpa-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:138) ~[spring-data-jpa-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.1.9.RELEASE.jar:2.1.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at com.sun.proxy.$Proxy193.getAllGroupSummary(Unknown Source) ~[na:na]
    at com.telus.msmb.services.impl.UserGroupServiceImpl.
D. Lawrence
  • 943
  • 1
  • 10
  • 23
Zubair
  • 5,833
  • 3
  • 27
  • 49
  • what is exactly not clear about this? Your `com.telus.msmb.services.impl.UserGroupServiceImpl` calls that repository and does `List.get(0)` somewhere, but the query did not return anything. – Eugene Mar 06 '20 at 14:48
  • @Eugene the query return the following result when run from mysql console: Administrators 2 0 0 Notifiable 1 1 1 I have added the screenshot for you as well. – Zubair Mar 06 '20 at 14:59
  • I don't care what that query returns from console (and neither should you) - code does _not_ lie. – Eugene Mar 06 '20 at 15:01
  • Could you run the query in Sql IDE and see any results? If there are results, then go to next steps like, logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE to see more logs on console. – Vipul Mar 06 '20 at 15:02
  • @Eugene you understanding is not correct. If i change the method to: List getAllGroupSummary(); it does return the objects...you are not gettign the point..my friend. – Zubair Mar 06 '20 at 15:03
  • Hibernate: SELECT b.name, b.id, count(u.user_id) as total_user, sum(case u.is_active when true then 1 else 0 end) as active_user FROM user_group b LEFT JOIN user u ON u.group_id = b.id GROUP BY b.name, b.id order by b.name ASC; – Zubair Mar 06 '20 at 15:04
  • I got it. List> is incorrect. Your query returns list of objects but not list of map. Once you get list of results, you write code manually to convert to list of map. – Vipul Mar 06 '20 at 15:04
  • of course my understanding is not correct - it's _you_ that has not provided all the details? – Eugene Mar 06 '20 at 15:06
  • @Vipul, I got your point...but the strange thing is it was working fine a day before... – Zubair Mar 06 '20 at 15:07
  • @Eugene you are right..now I have provided all the details...any thoughts – Zubair Mar 06 '20 at 15:08
  • 2
    @Zubair, If you see results , you wont get a map from list of objects. You could use Hql to get a list of map. That query no way returns list of map, just analyze , look at results and your return type. What can be the key and value here. – Vipul Mar 06 '20 at 15:10
  • 2
    once you get list of objects, you could use list.stream().map method to transform to your required value. – Vipul Mar 06 '20 at 15:11
  • @Vipul can we get column names as well ? – Zubair Mar 06 '20 at 15:29
  • @Zubair easy thing to do, use a model object, so you get a list of summary model objects. – Vipul Mar 06 '20 at 16:44
  • https://stackoverflow.com/questions/7595328/jpa-2-0-native-query-results-as-map Please check this link. – Vipul Mar 06 '20 at 16:51

1 Answers1

0

It will return a list of UserGroup instead of MAP of String and object. You should change your return object. Once you get the list, you can process your list to change to map using lambda or by iterating it.

PearlGrey
  • 29
  • 1
  • 7
  • @PearlyGray, zubair did not provide complete details on how he is accessing getAllGroupSummary method. I think he is using getResultList() method to retrieve data, that method returns list of column and values. – Vipul Mar 06 '20 at 16:53