I have looked at a few other postings to try and solve this issue.
Clarification around Spring-AOP pointcuts and inheritance
Spring AOP pointcut that matches annotation on interface
I have a scenario where we have some base interfaces that define some high level methods for data access (strongly typed via generics). I then have an interface that implements essentially overrides/reimplements the same methods in order to strongly type them and to provide JAX-WS annotations. The interesting point is that even though I redefine the methods within this interface, the Spring AOP pointcuts will not accept the pointcut and start a Transaction...so I get an error via Spring/JPA/Hibernate "Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress".
We have other "services" that utilize Spring AOP successfully, but they don't inherit Generic methods from a super interface.
This is the top level class:
public interface BaseCoreDataService<O extends Comparable<O>, T extends DomainModel<O>> extends BaseService {
@WebMethod(exclude = true)
BaseDao<O, T> getBaseDao();
O save(T model);
}
Which is inherited/extended by this interface (adding another method):
public interface BaseSimpleDataService<O extends Comparable<O>, T extends DomainModel<O>> extends
BaseCoreDataService<O, T> {
T get(O id);
}
Which is finally inherited/extended with this interface that strongly types the Generic and provide the JAX-WS annotations:
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;
}
So if I include the following pointcut, the invocation blows an exception that a transaction does not exist:
<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>
But if I add in an additional advisor/pointcut for the parent classes, the transaction works and saves/gets essentially succeed:
<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>
I am not sure if the issue revolves around inheritance of interfaces? The odd thing is that in this final interface UserDataService, I have all the methods redefined...but this still fails when invoking save/get with a "no transaction in progress", even though the stacktrace includes Spring AOP classes.
So adding the additional advisor/pointcut fixes it, I just want to understand why?