Question

I've configured Spring solely based on XML. Transactions are managed by Hibernate, and I'm using AOP to manage transaction boundaries.

However, when running unit tests, why is it that my AOP configuration not kicks in? I need to add annotations such as @Transactional to the test method to make sure that database operations gets wrapped in transactions, even though I've configured AOP to wrap calls to service methods in transactions.

Why doesn't my AOP configuration apply to tests also?

applicationcontext.xml

<aop:aspectj-autoproxy/>

<!-- Data Source -->
<bean id="companyDomainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.master.url}" />
    <property name="user" value="${jdbc.master.username}" />
    <property name="password" value="${jdbc.master.password}" />         
    <property name="acquireIncrement" value="1" />
    <property name="minPoolSize" value="2" />
    <property name="maxPoolSize" value="20" />
    <property name="maxIdleTime" value="4" />        
</bean>

<!-- Session Factory -->
<bean id="companyDomainSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="companyDomainDataSource"/>
    <property name="mappingResources">
        <list>
            <value>/com/company/pas/entity/mapping/partner.hbm.xml</value>
        </list>
    </property>
</bean>    

<!-- Transaction Manager -->
<bean id="companyDomainTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="companyDomainSessionFactory"/>
</bean>

<!-- Transaction Advice -->
<tx:advice id="companyDomainTransactionAdvise" transaction-manager="companyDomainTransactionManager">
    <tx:attributes>
        <!--<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>-->
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<aop:config>        
    <aop:pointcut id="serviceMethods" expression="within(com.company.pas.dao.*)"/>
    <aop:advisor advice-ref="companyDomainTransactionAdvise" pointcut-ref="serviceMethods"/>
</aop:config> 

unit test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
@TransactionConfiguration(transactionManager="companyDomainTransactionManager", defaultRollback=true)
public class PartnerCreateTest extends AbstractActionTest {

    @Autowired @Qualifier("createPartnerAction") AbstractAction action;

    @Test
    @Transactional
    public void testExecute() throws Exception {

        // Create partner.
        Representation rep = mock(Representation.class);
        Request req = mock(Request.class);
        Response resp = mock(Response.class);        

        when(rep.getText()).thenReturn(getContentsOf("com/company/pas/entity/xml/partner-create.xml"));
        when(req.getEntity()).thenReturn(rep);

        AbstractRequestModel crm = action.getRequestModelParser().parse(req, resp);
        action.execute(crm);

    }

}
Was it helpful?

Solution

When you add @Transactional to a test method you get a rollback by default. When you don't you should expect transactions to commit (they don't know they are in a test).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top