Kuali Rice Development
  1. Kuali Rice Development
  2. KULRICE-10916

Sorting is broken for tables using server side paging

    Details

    • Type: Bug Fix Bug Fix
    • Status: Closed Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.4
    • Fix Version/s: 2.4
    • Component/s: Development
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-4724Client side table sorting, paging
      KULRICE-10109Continue Server Side Paging Work - Column/Row Span
      KULRICE-11945Actions column header disappears with server side paging
      KULRICE-12963Table page gets built twice initially when server side paging is enabled
      KULRICE-13083Implement a way to set up server side custom sorts for server side paging collections
      KULRICE-11071KRAD Demo Library Collection Features Server Paging Stacked Collection with server-side paging and Table Collection with server-side Paging not paging
      KULRICE-11936Library - Collections - server side Paging (rich table only) - records displayed, then disappear
      KULRICE-11935Library Collections Lookup sample (server side paging) has no rows returned
      KULRICE-12470KRAD Sampleapp Labs Course Search Rich Table Server Side Paging displays empty result after showing results
      KULRICE-10534Multivalue lookup server side select for server side paging
    • Rice Module:
      KRAD
    • KRAD Feature Area:
      UIF Component
    • Sprint:
      2.4.0-m2 KRAD Sprint 4
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required
    • Code Review Status:
      Not Required
    • Include in Release Notes?:
      Yes

      Description

      Sorting is broken when server paging is enabled. To reproduce in the KRAD sample app:

      • Navigate to Library -> Collections -> Server Paging
      • Click on the header for any sortable column

      You'll get a JS alert similar to "DataTables warning (table id = 'u100101'): DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error."

      In the server log you'll get a stack trace:

      java.lang.IllegalStateException: View context is not active
      	at org.kuali.rice.krad.uif.component.ComponentBase.copy(ComponentBase.java:2192)
      	at org.kuali.rice.krad.uif.util.MultiColumnComparator.buildPrototypeRow(MultiColumnComparator.java:406)
      	at org.kuali.rice.krad.uif.util.MultiColumnComparator.<init>(MultiColumnComparator.java:103)
      	at org.kuali.rice.krad.web.controller.helper.DataTablesPagingHelper.applyTableJsonSort(DataTablesPagingHelper.java:223)
      	at org.kuali.rice.krad.web.controller.helper.DataTablesPagingHelper.processPagingRequest(DataTablesPagingHelper.java:80)
      	at org.kuali.rice.krad.web.controller.UifControllerBase.tableJsonRetrieval(UifControllerBase.java:1243)
      	at org.kuali.rice.krad.web.controller.UifControllerBase$$FastClassByCGLIB$$7929303a.invoke(<generated>)
      	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
      	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
      	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
      	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
      	at org.kuali.rice.krad.demo.uif.controller.ServerPagingTestController$$EnhancerByCGLIB$$28bb2b06.tableJsonRetrieval(<generated>)
      	at sun.reflect.GeneratedMethodAccessor771.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
      	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
      	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
      	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
      	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
      	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
      	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
      	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
      	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
      	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
      	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.krad.web.filter.CharsetFilter.doFilter(CharsetFilter.java:58)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:89)
      	at org.kuali.rice.krad.web.filter.UserLoginFilter.doFilter(UserLoginFilter.java:77)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:327)
      	at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:82)
      	at org.kuali.rice.krad.web.filter.DummyLoginFilter.doFilter(DummyLoginFilter.java:62)
      	at org.kuali.rice.krad.web.filter.BootstrapFilterChain.doFilter(BootstrapFilter.java:320)
      	at org.kuali.rice.krad.web.filter.BootstrapFilter.doFilter(BootstrapFilter.java:199)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.krad.web.filter.UifSessionTimeoutFilter.doFilter(UifSessionTimeoutFilter.java:106)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.core.web.Log4JContextClearingFilter.doFilterInternal(Log4JContextClearingFilter.java:37)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.kuali.rice.krad.web.filter.HideWebInfFilter.doFilter(HideWebInfFilter.java:68)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:213)
      	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
      	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
      	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
      	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
      	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
      	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
      	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
      	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
      	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
      	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:182)
      	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
      	at java.lang.Thread.run(Thread.java:662)
      

        Activity

        Hide
        Peter Giles (Inactive) added a comment -

        Hi Mark, the sort for server paging broke somewhere in this cluster of commits last friday: r41980, r41981, r41982. The MultiColumnComparator is (on line 406) copying components for use as prototypes, and this is happening when the view state is not active. I'm not sure why it's forbidden to copy components at that time. Can you please take a look? Thanks

        Show
        Peter Giles (Inactive) added a comment - Hi Mark, the sort for server paging broke somewhere in this cluster of commits last friday: r41980, r41981, r41982. The MultiColumnComparator is (on line 406) copying components for use as prototypes, and this is happening when the view state is not active. I'm not sure why it's forbidden to copy components at that time. Can you please take a look? Thanks
        Hide
        Mark Fyffe (Inactive) added a comment -

        Hi Peter - I'll look into this over the weekend. It should be relatively straightforward to address. I'll follow up with details tomorrow or Sunday.

        Show
        Mark Fyffe (Inactive) added a comment - Hi Peter - I'll look into this over the weekend. It should be relatively straightforward to address. I'll follow up with details tomorrow or Sunday.
        Hide
        Mark Fyffe (Inactive) added a comment -

        Committed a fix.

        Since MultiColumnComparator creates copies of selected components from the posted view, it needs to be encapsulated in a lifecycle or initialization call to enable modification. Since the sorting isn't really part of the lifecycle, I wrapped the MultiColumnComparator constructor in an encapsulateInitialization call() and am no longer seeing this issue.

        @@ -224,7 +225,13 @@
                         sortIndices[i] = i;
                     }
        
        -            Arrays.sort(sortIndices, new MultiColumnComparator(modelCollection, collectionGroup, newColumnSorts, view));
        +            MultiColumnComparator comparator = ViewLifecycle
        +                    .encapsulateInitialization(new Callable<MultiColumnComparator>(){
        +                @Override
        +                public MultiColumnComparator call() throws Exception {
        +                    return new MultiColumnComparator(modelCollection, collectionGroup, newColumnSorts, view);
        +                }});
        +            Arrays.sort(sortIndices, comparator);
        
                     // apply the sort to the modelCollection
                     Object[] sorted = new Object[sortIndices.length];
        
        Show
        Mark Fyffe (Inactive) added a comment - Committed a fix. Since MultiColumnComparator creates copies of selected components from the posted view, it needs to be encapsulated in a lifecycle or initialization call to enable modification. Since the sorting isn't really part of the lifecycle, I wrapped the MultiColumnComparator constructor in an encapsulateInitialization call() and am no longer seeing this issue. @@ -224,7 +225,13 @@ sortIndices[i] = i; } - Arrays.sort(sortIndices, new MultiColumnComparator(modelCollection, collectionGroup, newColumnSorts, view)); + MultiColumnComparator comparator = ViewLifecycle + .encapsulateInitialization(new Callable<MultiColumnComparator>(){ + @Override + public MultiColumnComparator call() throws Exception { + return new MultiColumnComparator(modelCollection, collectionGroup, newColumnSorts, view); + }}); + Arrays.sort(sortIndices, comparator); // apply the sort to the modelCollection Object[] sorted = new Object[sortIndices.length];
        Hide
        Adam Campbell (Inactive) added a comment -

        validated on env14
        closing as fixed

        Show
        Adam Campbell (Inactive) added a comment - validated on env14 closing as fixed

          People

          • Assignee:
            Mark Fyffe (Inactive)
            Reporter:
            Peter Giles (Inactive)
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 1 day, 4 hours
              1d 4h
              Remaining:
              Time Spent - 4 hours Remaining Estimate - 1 day
              1d
              Logged:
              Time Spent - 4 hours Remaining Estimate - 1 day
              4h

                Agile

                  Structure Helper Panel