{"action":"opened","issue":{"url":"https://api.github.com/repos/jembi/bsis/issues/444","labels_url":"https://api.github.com/repos/jembi/bsis/issues/444/labels{/name}","comments_url":"https://api.github.com/repos/jembi/bsis/issues/444/comments","events_url":"https://api.github.com/repos/jembi/bsis/issues/444/events","html_url":"https://github.com/jembi/bsis/issues/444","id":122740673,"number":444,"title":"Duplicate Donor merge functionality is broken","user":{"login":"timler","id":1272356,"avatar_url":"https://avatars.githubusercontent.com/u/1272356?v=3","gravatar_id":"","url":"https://api.github.com/users/timler","html_url":"https://github.com/timler","followers_url":"https://api.github.com/users/timler/followers","following_url":"https://api.github.com/users/timler/following{/other_user}","gists_url":"https://api.github.com/users/timler/gists{/gist_id}","starred_url":"https://api.github.com/users/timler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timler/subscriptions","organizations_url":"https://api.github.com/users/timler/orgs","repos_url":"https://api.github.com/users/timler/repos","events_url":"https://api.github.com/users/timler/events{/privacy}","received_events_url":"https://api.github.com/users/timler/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-12-17T14:04:36Z","updated_at":"2015-12-17T14:04:36Z","closed_at":null,"body":"The merge duplicate donors wizard is broken after the preview. \r\n\r\nThis was caused by the change in revision 90ead799da6c7b752026ce15f6c56d84f639135b where the DonorService.setDonorDueToDonate method was changed to use a database function to calculate the next donation date for a donor.\r\n\r\nThe issue is that at the preview step of the merge duplicate donor wizard the new merged donor has not been persisted in the database.\r\n\r\nSadly, there weren't any unit tests for the method `getAllDonationsToMerge` in `DuplicateDonorService` which would (or at least might) have been able to pick up the issue.\r\n\r\nException seen on the bsis server:\r\n\r\n```\r\n15:37:21,547 BSIS_CLICK_LOG bsis:23 - http://localhost:8080/bsis/donors/duplicates/merge/preview?donorNumber=000011\r\n15:37:22,582  INFO BloodTestingRuleEngine:90 - BloodTestingRuleEngine running for donation with id '12' and donor with number '000011' using available test results = {1=A, 17=POS, 18=NEG, 19=NEG, 2=POS, 20=NEG, 23=NEG, 26=POS, 27=POS, 28=POS, 3=LOW, 4=NEG}\r\njava.lang.NullPointerException\r\n\tat service.DonorService.setDonorDueToDonate(DonorService.java:36)\r\n\tat service.DonorService$$FastClassBySpringCGLIB$$1d3f3828.invoke(<generated>)\r\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\r\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)\r\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)\r\n\tat service.DonorService$$EnhancerBySpringCGLIB$$7b360fcf.setDonorDueToDonate(<generated>)\r\n\tat service.DuplicateDonorService.executeTestsAndUpdate(DuplicateDonorService.java:178)\r\n\tat service.DuplicateDonorService.getAllDonationsToMerge(DuplicateDonorService.java:135)\r\n\tat service.DuplicateDonorService$$FastClassBySpringCGLIB$$f4121381.invoke(<generated>)\r\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\r\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)\r\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)\r\n\tat service.DuplicateDonorService$$EnhancerBySpringCGLIB$$6f418108.getAllDonationsToMerge(<generated>)\r\n\tat controller.DonorController.findDuplicateDonorsDonations(DonorController.java:419)\r\n\tat controller.DonorController$$FastClassBySpringCGLIB$$54ff8830.invoke(<generated>)\r\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\r\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)\r\n\tat org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)\r\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)\r\n\tat controller.DonorController$$EnhancerBySpringCGLIB$$49bfdc7c.findDuplicateDonorsDonations(<generated>)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.lang.reflect.Method.invoke(Method.java:606)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:647)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:728)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)\r\n\tat org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)\r\n\tat org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)\r\n\tat org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)\r\n\tat org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)\r\n\tat org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)\r\n\tat org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)\r\n\tat org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat utils.CORSFilter.doFilter(CORSFilter.java:27)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)\r\n\tat org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)\r\n\tat org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)\r\n\tat org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)\r\n\tat org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)\r\n\tat java.lang.Thread.run(Thread.java:745)\r\n\r\n```"}}