我已经查看过其他一些帖子,试图解决这个问题。
Clarification around Spring-AOP pointcuts and inheritance
Spring AOP pointcut that matches annotation on interface
我有一个场景,我们有一些基本接口定义了一些高级数据访问方法(通过泛型强类型)。然后我有一个接口实现了基本上覆盖/重新实现相同的方法,以便强类型化它们并提供JAX-WS注释。有趣的是,即使我重新定义了这个接口中的方法,Spring AOP切入点也不会接受切入点并启动一个Transaction ...所以我通过Spring / JPA / Hibernate得到一个错误“引起:javax.persistence。 TransactionRequiredException:没有正在进行的事务“。
我们有其他成功利用Spring AOP的“服务”,但它们不会从超级接口继承Generic方法。
这是顶级课程:
public interface BaseCoreDataService<O extends Comparable<O>, T extends DomainModel<O>> extends BaseService {
@WebMethod(exclude = true)
BaseDao<O, T> getBaseDao();
O save(T model);
}
由此接口继承/扩展(添加另一种方法):
public interface BaseSimpleDataService<O extends Comparable<O>, T extends DomainModel<O>> extends
BaseCoreDataService<O, T> {
T get(O id);
}
最后继承/扩展了这个强类型Generic并提供JAX-WS注释的接口:
public interface UserDataService extends BaseSimpleDataService<Long, User> {
@RequestWrapper(localName = "GetUserById", className = "com.foo.UserDataService.GetUserById", targetNamespace = "http://foo.com")
@ResponseWrapper(localName = "GetUserByIdResponse", className = "com.foo.UserDataService.GetUserByIdResponse", targetNamespace = "http://foo.com")
@WebResult(targetNamespace = "http://foo.com", name = "User")
@WebMethod(operationName = "getUserById")
User get(@WebParam(targetNamespace = "http://foo.com", name = "Id") Long id)
throws ValidationException;
@RequestWrapper(localName = "SaveUser", className = "com.foo.UserDataService.SaveUser", targetNamespace = "http://foo.com")
@ResponseWrapper(localName = "SaveUserResponse", className = "com.foo.UserDataService.SaveUserResponse", targetNamespace = "http://foo.com")
@WebResult(targetNamespace = "http://foo.com", name = "Id")
@WebMethod(operationName = "saveUser")
Long save(
@WebParam(targetNamespace = "http://foo.com", name = "User") User model)
throws ValidationException;
}
因此,如果我包含以下切入点,则调用会导致事务不存在的异常:
<bean id="GlobalDataTransactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"
p:transactionManagerName="javax.transaction.TransactionManager"/>
<tx:advice id="GlobalDataTxAdvice" transaction-manager="GlobalDataTransactionManager">
<tx:attributes>
<tx:method name="get*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
<tx:method name="find*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
<tx:method name="search*" timeout="60" no-rollback-for="javax.persistence.NoResultException,javax.persistence.NonUniqueResultException,org.springframework.dao.EmptyResultDataAccessException"/>
<tx:method name="*" timeout="60"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo..UserDataService.*(..))"/>
</aop:config>
但是,如果我为父类添加额外的顾问程序/切入点,则事务可以正常工作并且保存/获取基本上成功:
<aop:config>
<aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo..UserDataService.*(..))"/>
<aop:advisor advice-ref="GlobalDataTxAdvice" pointcut="execution(* com.foo.core.*DataService.*(..))"/>
</aop:config>
我不确定问题是否围绕接口的继承?奇怪的是,在这个最终接口UserDataService中,我重新定义了所有方法......但是当使用“无事务正在进行”调用save / get时,这仍然失败,即使堆栈跟踪包含Spring AOP类。
所以添加额外的顾问/切入点修复它,我只想了解原因?