Question

I am trying to alter an argument in being passed to a JdbcOperation query method. Basically the SQL Statement that is the 1st parameter (String) being passed to the jdbcTemplate.query() Method needs to be altered. I want to surround any statement in an additional SQL SELECT. The SELECT works fine when run on the DB backend OR when I hard code it. I think the arguments are being auto filled correctly by query() after the jp.Proceed() is called after I edit jp.getArgs()[0]. You can see that from the Log Entries that lead up to the java.lang.NullPointerException. I think the NullPointerException is a result of zero rows being returned from the Query (guess). It's as if the arguments that are altered in the Aspect aren't getting through when the query is executed on the Database.

My SqlLoggerAspect Aspect looks like this:

@Around("execution(* org.springframework.jdbc.core.JdbcOperations.*(String, ..))")
    public void log(final ProceedingJoinPoint jp) throws Throwable {

        Object[] methodArgs = jp.getArgs(), sqlArgs = null;
        CustomUser customUser = (CustomUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        methodArgs[0] = new String ("SELECT * FROM (" + methodArgs[0] + 
                ") AS domain_object WHERE (ktn = "+ customUser.getKtn() +") OR (ktn is NULL)");
        jp.proceed(methodArgs);
}

Here's how I Query the Database:

sySectionsList.addAll(jdbcTemplate.query("SELECT * FROM sy_section WHERE stn_code=?", sySectionMapper, sySection.getStn_code()));

My Spring Bean Config looks like this:

<aop:aspectj-autoproxy proxy-target-class="true">
    <aop:include name = "sqlLogger"/>
</aop:aspectj-autoproxy>

<aop:config proxy-target-class="true">
</aop:config>

<bean id="sqlLogger" class="ie.cit.pro.aspects.SqlLoggerAspect" />

This all results in a perfectly formed SQL Statement (which I can see in the TRACE Log after the jp.Proceed() is called) that works fine when I execute on the DB backend OR when I hardcode it in the application. However i Get a NullPointerException which I think could be because at runtime no records are being returned to my RowMapper. My Error is as follows:

DEBUG 2014-02-04 06:42:14,769 org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL query
DEBUG 2014-02-04 06:42:14,769 org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT * FROM (SELECT * FROM sy_section WHERE stn_code=?) AS domain_object WHERE (ktn = 1) OR (ktn is NULL)]
DEBUG 2014-02-04 06:42:14,769 org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
DEBUG 2014-02-04 06:42:14,769 org.springframework.jdbc.datasource.SimpleDriverDataSource - Creating new JDBC Driver Connection to [jdbc:h2:mem:dataSource;DB_CLOSE_DELAY=-1]
TRACE 2014-02-04 06:42:14,771 org.springframework.jdbc.core.StatementCreatorUtils - Setting SQL statement parameter value: column index 1, parameter value [-WFBWLD101], value class [java.lang.String], SQL type unknown
DEBUG 2014-02-04 06:42:14,773 org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
DEBUG 2014-02-04 06:42:14,774 org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String ie.cit.pro.web.FbController.weldtrack(org.springframework.ui.Model,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String)]: java.lang.NullPointerException
DEBUG 2014-02-04 06:42:14,777 org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String ie.cit.pro.web.FbController.weldtrack(org.springframework.ui.Model,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String)]: java.lang.NullPointerException
DEBUG 2014-02-04 06:42:14,777 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.lang.String ie.cit.pro.web.FbController.weldtrack(org.springframework.ui.Model,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String)]: java.lang.NullPointerException
TRACE 2014-02-04 06:42:14,777 org.springframework.web.servlet.DispatcherServlet - Cleared thread-bound request context: SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.savedrequest.SavedRequestAwareWrapper@4e57dc21]
DEBUG 2014-02-04 06:42:14,778 org.springframework.web.servlet.DispatcherServlet - Could not complete request
java.lang.NullPointerException
    at ie.cit.pro.domain.dao.JdbcDataRepository.getSySectionsByCode(JdbcDataRepository.java:127)
    at ie.cit.pro.domain.dao.JdbcDataRepository$$FastClassByCGLIB$$1a306ee2.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.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
    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 ie.cit.pro.domain.dao.JdbcDataRepository$$EnhancerByCGLIB$$c8a61982.getSySectionsByCode(<generated>)
    at ie.cit.pro.services.SyServiceImpl.getSySectionsByCode(SyServiceImpl.java:45)
    at ie.cit.pro.services.SyServiceImpl$$FastClassByCGLIB$$4c45712.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:627)
    at ie.cit.pro.services.SyServiceImpl$$EnhancerByCGLIB$$9e7f5ebf.getSySectionsByCode(<generated>)
    at ie.cit.pro.web.FbController.weldtrack(FbController.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    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:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    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:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    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:695)
Was it helpful?

Solution

Your aspect is wrong. You are returning void from your @Around method making every method that this aspect touches return null.

Around aspects must always return Object and you must always return the result of the call to proceed(). If you don't you will run into trouble.

@Around("execution(* org.springframework.jdbc.core.JdbcOperations.*(String, ..))")
public Object log(final ProceedingJoinPoint jp) throws Throwable {

    Object[] methodArgs = jp.getArgs(), sqlArgs = null;
    CustomUser customUser = (CustomUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

    methodArgs[0] = new String ("SELECT * FROM (" + methodArgs[0] + 
            ") AS domain_object WHERE (ktn = "+ customUser.getKtn() +") OR (ktn is NULL)");
    return jp.proceed(methodArgs);

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top