Spring AOP и интерфейсы с Generics (наследование) - PullRequest
1 голос
/ 30 марта 2012

Я рассмотрел несколько других публикаций, чтобы попытаться решить эту проблему.

Разъяснение о точечных вызовах и наследовании Spring-AOP

Pointcut точного АОПэто соответствует аннотации на интерфейсе

У меня есть сценарий, в котором у нас есть несколько базовых интерфейсов, которые определяют некоторые высокоуровневые методы доступа к данным (строго типизированные с помощью обобщений).Затем у меня есть интерфейс, который реализует, по существу, переопределяет / переопределяет те же методы, чтобы их строго печатать и предоставлять аннотации JAX-WS.Интересно то, что, хотя я переопределяю методы в этом интерфейсе, pointcutts Spring AOP не будет принимать pointcut и запускать транзакцию ... поэтому я получаю сообщение об ошибке через Spring / JPA / Hibernate "Причины: javax.persistence.TransactionRequiredException: ни одна транзакция не выполняется ".

У нас есть другие" службы ", которые успешно используют Spring AOP, но они не наследуют универсальные методы от суперинтерфейса.

Это вершинакласс уровня:

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;
}

Так что, если я включу следующий pointcut, вызов выдает исключение, что транзакция не существует:

<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>

Но если я добавлю вдополнительный советник / pointcut для родительских классов, транзакция работает и сохраняет / получает по существу успех:

<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 у меня все методы переопределены ... но все равно происходит сбой при вызове сохранения / получения с "транзакцией в процессе не выполняется", даже если трассировка стека включает классы Spring AOP.

Итак, добавление дополнительного советника / pointcut исправляет его, я просто хочу понять, почему?

...