Announcement Announcement Module
Collapse
No announcement yet.
Advice called twice (once for the implementation and once for the proxy) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    The transaction documentation has been extensively reworked in light of numerous improvements in Spring 2.0. The updated documentation ha no more [TODO] placeholders, and will be included in the next release.

    In the interim, here is an example of how one specifies the transaction manager that is to be used...

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx">
      
      <!-- this is the service object that we want to make transactional -->
      <bean id="fooService" class="x.y.service.DefaultFooService"/>
    
      <!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
      <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
        <tx:attributes>
          <!-- all methods starting with 'get' are read-only -->
          <tx:method name="get*" read-only="true"/>
          <!-- other methods use the default transaction settings (see below) -->
          <tx:method name="*"/>
        </tx:attributes>
      </tx:advice>
      
      <!-- this applies the above transactional advice to any FooService implementation bean -->
      <aop:config>
        <aop:advisor pointcut="execution(* *..FooService+.*(..))" 
                     advice-ref="txAdvice"/>
      </aop:config>
      
      <!-- don't forget the DataSource -->
      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
        <property name="username" value="scott"/>
        <property name="password" value="tiger"/>
      </bean>
    
      <!-- similarly, don't forget the (correct) PlatformTransactionManager -->
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>
      
      <!-- other <bean/> definitions here -->
    
    </beans>
    Cheers
    Rick

    Comment


    • #17
      Advice called twice (once for the implementation and once for the proxy)

      Hi Weslen,

      Define the pointcut on implemented class. Otherwise advisor gets called twice if point cut is defined on interface.

      Comment


      • #18
        Got the same issue, even if I hardcoded the name of my implementation in the pointcut expression (the interface is IContractService).

        Here is my configuration :
        Code:
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="*" read-only="false" />
            </tx:attributes>
        </tx:advice>
        
        <bean id="exceptionLoggerAdvice" class="fr.socle.log.ExceptionLoggerService">
             <property name="loggerName" value="fr.applicationblanche.services" />
        </bean>
        
        <aop:config>
           <aop:pointcut id="servicePointcut"expression="execution(* fr.applicationblanche.services.DefaultContractService.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
            <aop:aspect id="afterService" ref="exceptionLoggerAdvice">
                <aop:after-throwing throwing="exception" method="afterThrowing" pointcut-ref="servicePointcut" />
            </aop:aspect>
        </aop:config>
        Both of my aspects are executed twice : no matter with the tx one which create 2 nested transactions with the same behavior (commit 2x or rollback 2x) but it's really bothering me with my loggerAdvice which logs every exception twice.

        Any advice ? ( )

        Comment


        • #19
          Do not know if this thread is still alive but I came accross the same symptom : MethodInterceptor advice and around advice being called twice.

          I searched thru all my spring context config files and find out that I had the following declarations :

          <aop:config proxy-target-class="true" />

          <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy .DefaultAdvisorAutoProxyCreator">
          <property name="proxyTargetClass"><value>true</value></property>
          </bean>

          By removing the second declaration this solved my problem.

          Actually this is well documented in chapter 6.3 (Spring 2.0.x) :

          "The <aop:config> style of configuration makes heavy use of Spring's auto-proxying mechanism. This can cause issues (such as advice not being woven) if you are already using explicit auto-proxying via the use of BeanNameAutoProxyCreator or suchlike. The recommended usage pattern is to use either just the <aop:config> style, or just the AutoProxyCreator style."

          Maybe you have similar redundant declarations.

          Comment


          • #20
            Declare Ponicut at class level

            like
            @Pointcut("execution(* com.abc.service.impl.TestClass.*(..))")

            Comment

            Working...
            X