Saturday, 15 February 2014

spring-mvc-test auto rollback transactions configured with AOP xml on Service layer -



spring-mvc-test auto rollback transactions configured with AOP xml on Service layer -

i have next spring mvc app stack:

controller -> service -> dao (repository) -> entity -> mysql innodb

transactions configured start service layer using aop xml config, , app works perfectly:

<aop:config> <aop:advisor id="managertx" advice-ref="txadvice" pointcut="execution(* *..service.*service.*(..))" order="1"/> </aop:config> <aop:aspectj-autoproxy proxy-target-class="true"/> <tx:advice id="txadvice"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice>

now, writing spring mvc tests using spring-mvc-test framework, unitdb etc. test class has next config:

@runwith(springjunit4classrunner.class) @contextconfiguration( loader=webcontextloader.class, locations={ "classpath:spring/testcontext.xml", "classpath:spring/testdispatcher-servlet.xml", "classpath:spring/security.xml" }) @testexecutionlisteners({ dependencyinjectiontestexecutionlistener.class, dirtiescontexttestexecutionlistener.class, transactionaltestexecutionlistener.class, dbunittestexecutionlistener.class }) @transactionconfiguration(transactionmanager="transactionmanager", defaultrollback=true) @transactional(propagation=propagation.required, rollbackfor={exception.class}) @databasesetup({"classpath:dbunit/initial-data.xml"})

the test looks this:

@test public void testsomecontroller() throws exception { this.mockmvc.perform(get("/some/controller")); }

basically want test (use) existing spring aop config within testing environment, setup db data, run tests , rollback after tests completed.

in above configuration, tests starting own transaction in given propagation config meeting transaction @ service layer, started aop xml config , lock timeout error, because transaction started test waiting transaction started aop config @ service layer.

i writing tests , shouldn't modifying actual code, test code. task to find way rollback changes made tests given configuration.

any ideas appreciated.

edit

here problematic case:

test class starts 1 big new transaction auto-rollback tests. dbunit fills db initial data test launches controller test controller makes phone call service layer e.g. save/update entity (inserted dbunit @ origin of test class), new transaction started here @ service layer (configured aop:config) supported big transaction step #1 boom, error happens: lock wait timeout exceeded; seek restarting transaction

i think info inserted dbunit still not committed because in same transaction. need find way insert initial info dbunit in separate transaction still roll @ end of test.

i did 3 things made work:

changed dbunittestexecutionlistener.class transactiondbunittestexecutionlistener.class

made test class extend abstracttransactionaljunit4springcontexttests

public class somecontrollertest extends abstracttransactionaljunit4springcontexttests

change info source org.apache.commons.dbcp.basicdatasource org.springframework.jdbc.datasource.transactionawaredatasourceproxy follows:

<bean id="datasource" class="org.springframework.jdbc.datasource.transactionawaredatasourceproxy"> <constructor-arg ref="dbcpdatasource"/> </bean> <bean id="dbcpdatasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close"> <property name="driverclassname" value="${jdbc.driverclassname}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxactive" value="100"/> <property name="maxwait" value="1000"/> <property name="poolpreparedstatements" value="true"/> <property name="defaultautocommit" value="true"/> <property name="validationquery" value="select 1+1"/> <property name="testonborrow" value="true"/> </bean>

hope helps someone

spring-aop spring-transactions dbunit spring-mvc-test spring-test-dbunit

No comments:

Post a Comment