我有一个使用Spring 4.1.0的Spring MVC应用程序。我的部分代码是由MyEclipse生成的,因为由于数据库更改,我经常不得不重新生成它,所以我选择使用方面向生成的类添加方法和属性,而不会在每次重新生成时丢失自定义。
最近我决定摆脱Eclipse构建,并希望改用Maven。我得到了一个Bamboo服务器,找到了我需要的所有依赖项,并且构建似乎完成得很好。但是,当我使用maven部署到tomcat的WAR时,我遇到了一个问题:我添加方面的方法无法捕获自己引发的异常。例如,这是我用来向生成的类添加方法的一个方面:
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如何构建这一点以及独立maven与aspectj-maven-plugin如何管理事物有一些根本的区别(这也是由于独立maven创建了一堆$ AjcClosureXXX.class文件这一事实暗示,如果我用Eclipse构建。
任何人都可以向正确的方向提供指针吗?我是否从根本上误解了maven构建此代码的方式与Eclipse的工作方式有关?
答案 0 :(得分:0)
你所看到的是Spring JpaExceptionTranslatorAspect
来自spring-aspects
的行动。它将调用网站包含在EntityManager
,EntityManagerFactory
,EntityTransaction
和Query
的方法中,并转换这些方法调用中引发的异常并使用特定于Spring的{{1}包装它们} subtype如果可能的话。
基于Eclipse的构建与Maven构建之间的差异很可能是您的Eclipse构建使用Java编译器,而Maven构建使用的是AspectJ编译器或Java编译器和 AspectJ编织器。所以Spring DataAccessException
确实在基于Maven的构建中生效,但在基于Eclipse的构建中不生效。
尝试捕获特定于Spring的包装器JpaExceptionTranslatorAspect
而不是EmptyResultDataAccessException
或禁用NoResultException
,以便不转换JPA异常。
此外,您应该将AJDT(AspectJ开发工具)插件安装到Eclipse中,并将项目配置为使用AspectJ编译器而不是Java编译器,以便您的Eclipse和Maven构建相同。