jfianl结合springboot sql异常不能全部暴露出来

@Aspect
@Component
public class JFinalTxAop {

    @Pointcut(value = "@annotation(com.warewms.common.annotation.JFinalTx)")
    private void jFinalTx() {}

    @Around(value = "jFinalTx()", argNames = "pjp")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal = null;
        Config config = getConfigWithTxConfig(pjp);
        if (config == null)
            config = DbKit.getConfig();

        Connection conn = config.getThreadLocalConnection();
        // Nested transaction support
        if (conn != null) {
            try {
                if (conn.getTransactionIsolation() < getTransactionLevel(config))
                    conn.setTransactionIsolation(getTransactionLevel(config));
                retVal = pjp.proceed();
                return retVal;
            } catch (SQLException e) {
                throw new ActiveRecordException(e);
            }
        }

        Boolean autoCommit = null;
        try {
            conn = config.getConnection();
            autoCommit = conn.getAutoCommit();
            config.setThreadLocalConnection(conn);
            // conn.setTransactionIsolation(transactionLevel);
            conn.setTransactionIsolation(getTransactionLevel(config));

            conn.setAutoCommit(false);
            retVal = pjp.proceed();
            conn.commit();
        } catch (NestedTransactionHelpException e) {
            if (conn != null) try {conn.rollback();} catch (Exception e1) {LogKit.error(e1.getMessage(), e1);}
            LogKit.logNothing(e);
        } catch (Throwable t) {
            if (conn != null) try {conn.rollback();} catch (Exception e1) {LogKit.error(e1.getMessage(), e1);}
            throw t instanceof RuntimeException ? (RuntimeException)t : new ActiveRecordException(t);
        }
        finally {
            try {
                if (conn != null) {
                    if (autoCommit != null)
                        conn.setAutoCommit(autoCommit);
                    conn.close();
                }
            } catch (Throwable t) {
                // can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
                LogKit.error(t.getMessage(), t);
            }
            finally {
                // prevent memory leak
                config.removeThreadLocalConnection();
            }
        }
        return retVal;
    }

    /**
     * 获取配置的事务级别
     * @param config
     * @return
     */
    protected int getTransactionLevel(Config config) {
        return config.getTransactionLevel();
    }

    /**
     * 获取配置的TxConfig,可注解到class或者方法上
     * @param pjp
     * @return Config
     */
    public static Config getConfigWithTxConfig(ProceedingJoinPoint pjp) {
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();
        TxConfig txConfig = method.getAnnotation(TxConfig.class);
        if (txConfig == null)
            txConfig = pjp.getTarget().getClass().getAnnotation(TxConfig.class);

        if (txConfig != null) {
            Config config = DbKit.getConfig(txConfig.value());
            if (config == null)
                throw new RuntimeException("Config not found with TxConfig: " + txConfig.value());
            return config;
        }
        return null;
    }
}

用jfianlTx注解来拦截services中的事务,但是如果出现异常则堆栈信息会是

com.jfinal.plugin.activerecord.ActiveRecordException: java.sql.SQLException: connection holder is null
	at com.jfinal.plugin.activerecord.Model.save(Model.java:533)
	at com.warewms.service.impl.AsnImportServiceImpl.importJsjyData(AsnImportServiceImpl.java:93)
	at com.warewms.service.impl.AsnImportServiceImpl$$FastClassBySpringCGLIB$$d8c6b9ce.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
	at com.warewms.config.JFinalTxAop.doAround(JFinalTxAop.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:643)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:632)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
	at com.warewms.service.impl.AsnImportServiceImpl$$EnhancerBySpringCGLIB$$1f50c66f.importJsjyData(<generated>)
	at com.warewms.dao.ProcTest.importAsn(ProcTest.java:40)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.sql.SQLException: connection holder is null
	at com.alibaba.druid.pool.DruidPooledConnection.checkStateInternal(DruidPooledConnection.java:1157)
	at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1148)
	at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:503)
	at com.jfinal.plugin.activerecord.Model.save(Model.java:525)
	... 50 more

无法把具体的sql异常信息暴露出来不知道该如何让错误完整暴露

评论区

快乐的蹦豆子

2019-08-24 18:34

打个断点就解决的问题

yjjdick1990

2019-08-24 19:00

@快乐的蹦豆子 站着说话不腰疼,我打了断电exception里的堆栈错误信息就是这个

yjjdick1990

2019-08-24 19:01

etVal = pjp.proceed();处出现的异常无法再深入跟踪

yjjdick1990

2019-08-24 21:51

@JFinal 波总记得前些年我按照你给的思路用AOP来实现springboot整合jfinal orm的案例(http://www.jfinal.com/feedback/3298),但是现在发现model的sql具体错误不能完全暴露,不知道该如何入手

JFinal

2019-08-24 21:54

@yjjdick1990 在几个 catch 块中设置断点,看异常信息是不是在那里

或许是某个地方吃掉了这些信息,只要找出吃掉的地点,就好解决

这个问题并不难解决

JFinal

2019-08-24 21:55

如果是 spring 吃掉的,那就很麻烦,否则你自己的代码要改起来是很容易的

JFinal

2019-08-24 21:57

有很多同学都将 jfinal 的 active record 模块用到 spring boot 中了,并未碰到你的这个问题,应该是好解决的

快乐的蹦豆子

2019-08-25 19:14

@yjjdick1990 顺着暴露的堆栈打断点,我不信就找不出来