繁体   English   中英

Spring 4.1.0和AspectJ:无法捕获异常

[英]Spring 4.1.0 and aspectj: cannot catch exceptions

我有一个使用Spring 4.1.0的Spring MVC应用程序。 我的部分代码是通过MyEclipse生成的,由于由于数据库的更改而不得不定期重新生成代码,因此我选择使用方面来向生成的类添加方法和属性,而不会因每次重新生成而丢失自定义。

最近,我决定摆脱Eclipse的构建,并想改用Maven。 我得到了一个Bamboo服务器,发现了我需要的所有依赖关系,并且构建似乎已经完成。 但是,当我将使用Maven进行的WAR部署到tomcat时,我遇到了一个问题:我在各方面添加的方法无法捕获自己提出的异常。 例如,这是我用来向生成的类添加方法的一个方面:

public Elementvalue ElementvalueDAOOligoExtension.getDrawdownRecoveryPeriod(Integer elementid, java.util.Calendar date, Double value, Integer elementvalueid, int startResult, int maxRows) throws DataAccessException {
    try {
        Query query = createNamedQuery("getDrawdownRecoveryPeriod", startResult, maxRows, elementid, date, value, elementvalueid);
        return (ch.oligofunds.oligoworld.domain.Elementvalue) query.getSingleResult();
    } catch (NoResultException nre) {
        return null;
    }
}

如您所见,其想法是,如果没有任何查询结果,则返回null(然后由调用方正确处理)。 但是,当调用此方法时,NoResultException实际上会冒泡到调用方,我可以在日志中找到它:

    org.springframework.dao.EmptyResultDataAccessException: No entity found for query; nested exception is javax.persistence.NoResultException: No entity found for query
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:392)
    at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:33)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect.getDrawdownRecoveryPeriod_aroundBody20(ElementvalueDAOImplAspect.aj:145)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect$AjcClosure21.run(ElementvalueDAOImplAspect.aj:1)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect.ajc$interMethod$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ElementvalueDAOOligoExtension$getDrawdownRecoveryPeriod(ElementvalueDAOImplAspect.aj:141)
    at ch.oligofunds.oligoworld.dao.ElementvalueDAOImpl.getDrawdownRecoveryPeriod(ElementvalueDAOImpl.java:1)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect.ajc$interMethodDispatch1$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ElementvalueDAOOligoExtension$getDrawdownRecoveryPeriod(ElementvalueDAOImplAspect.aj)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect.getDrawdownRecoveryPeriod_aroundBody18(ElementvalueDAOImplAspect.aj:137)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect$AjcClosure19.run(ElementvalueDAOImplAspect.aj:1)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63)
    at ch.oligofunds.oligoworld.aspects.dao.ElementvalueDAOImplAspect.ajc$interMethod$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ch_oligofunds_oligoworld_aspects_dao_ElementvalueDAOImplAspect$ElementvalueDAOOligoExtension$getDrawdownRecoveryPeriod(ElementvalueDAOImplAspect.aj:136)
    at ch.oligofunds.oligoworld.dao.ElementvalueDAOImpl.getDrawdownRecoveryPeriod(ElementvalueDAOImpl.java:1)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    ...

倒数第四行指向上面的代码行,在该行中我返回查询的单个结果。 因此,我希望那时的catch部分会捕获到NoResultException,这显然不会发生。

我应该指出,在Eclipse中构建时一切正常。 因此,我认为eclipse的构建方式和使用Aspectj-maven-plugin的独立Maven如何管理事物之间存在一些根本差异(这也由独立Maven创建了一堆$ AjcClosureXXX.class文件这一事实所暗示,如果我使用Eclipse构建)。

有人可以提供正确方向的指针吗? 关于Eclipse的执行方式,我是否对Maven构建此代码的方式有根本的误解?

您将看到实际上是从spring-aspectsJpaExceptionTranslatorAspect Spring的JpaExceptionTranslatorAspect 它将调用站点包装到EntityManagerEntityManagerFactoryEntityTransactionQuery ,并转换在这些方法调用中引发的异常,并在可能的情况下用Spring特定的DataAccessException子类型包装它们。

基于Eclipse的构建与Maven构建之间的差异很可能是因为Eclipse构建使用Java编译器,而Maven生成是使用AspectJ编译器或Java编译器 AspectJ编织器。 因此,Spring JpaExceptionTranslatorAspect确实会在基于Maven的构建中生效,但不会在基于Eclipse的构建中生效。

尝试捕获特定于Spring的包装器EmptyResultDataAccessException而不是NoResultException或禁用JpaExceptionTranslatorAspect这样就不会转换您的JPA异常。

另外,您应该将AJDT(AspectJ开发工具)插件安装到Eclipse中,并将您的项目配置为使用AspectJ编译器而不是Java编译器,以便Eclipse和Maven构建相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM