I have successfuly tested independent objects embedded within an EJB, using Springs org.springframework.test package. These tests were written so that any changes made to the database were rolled back at the end of each test case. I achieved this by making each test class extend the AbstractTransactionalDataSourceSpringContextTests Spring class.
However I'm having a problem trying to rollback tests I perform on a client object that accesses this remote EJB. As the client shouldn't live in an application container, I've got the test cases to fetch a UserTransaction object from the remote container using a JNDI lookup.
The UserTransaction object returned is then used to begin and rollback the transaction in the setup and teardown method of the client test class.
Unfortunately the rollback call doesn't actually do anything as the database keeps the changes made. I have this feeling that the transaction started on the client side is not picked up by the application container, or that the container has created a nested transaction thus preventing the clients rollback propagating to the database.
I've added the spring context xml file referring to the resources used and have addded the test class below. I've also added the method that retrieves the UserTransaction Object. I would be gratefull if anybody could be helpful here, as I've done a fair bit of reading on the internet trying to figure out where I'm going wrong.
<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pr opertyPlaceholderConfigurer">
<property name="location">
<value>com/convergys/rating/service/properties/JDBC.properties</value>
</property>
</bean>
<!-- The DrivingManagerDataSource will create a conection each time a call is made to the Database. Used for testing purposes and
developement. For production purposes Spring suggests using JndiObjectFactoryBean-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverM anagerDataSource">
<property name="driverClassName">
<value>${DataSource.DriverClassName}</value>
</property>
<property name="url">
<value>${DataSource.URL}</value>
</property>
<property name="username">
<value>${DataSource.Password}</value>
</property>
<property name="password">
<value>${DataSource.Username}</value>
</property>
</bean>
<!-- Transaction manager for a single JDBC DataSource (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSou rceTransactionManager">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
<!--<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager">
<property name="transactionManagerName">
<value>java:/UserTransaction </value>
</property>
</bean>-->
</beans>
************************************************** ********
public class CostCodeClientTest extends TestCase {
// static variable memebers when using no security
private static EJBconnectionHandler EJBconnection = null;
private static CostCodeService costCodeService = null;
// static constants
private final static String jndi_CostCodeBeanEntry = "Convergys/RB/CostCode";
private final static String environmentLocation = "t3://10.28.32.69:7005";
private final static String webLogicInitialContextFactory = "weblogic.jndi.WLInitialContextFactory";
/**
* JUnit creates an instance of this class for each test method defined below.
* Therefore it would make sense to define a static initializer to retrieve the costCode
* service object as the static initializer is only ever invoked by the classloader once.
*/
static {
try {
EJBconnection = new EJBconnectionHandler();
EJBconnection.generateInitCntxtWithoutSecurity(web LogicInitialContextFactory, environmentLocation);
EJBconnection.generateEjbObjectStub(jndi_CostCodeB eanEntry);
costCodeService = EJBconnection.getCostCodeService();
}
catch(Exception ex){
System.out.println("Error on retrieving the static bean member costCodeService");
}
}
private UserTransaction transaction = null;
/**
* <b> Method Name </b> setUp <br><br>
* <b> description </b> sets up the required resources for each test case,
* such retrieving a new transaction object with which to start a new transaction
*
* @throws Exception
* @author rdb
* @since 2.3
*/
public void setUp() throws Exception{
EJBconnection.generateTransactionObjectStub();
transaction = EJBconnection.getUserTransaction();
transaction.begin();
}
/**
* <b> Method Name </b> tearDown <br><br>
* <b> description </b> removes all tied in resources such as rolling back
* an active transaction and removing the transaction object
*
* @throws Exception
* @author rdb
* @since 2.3
*/
public void tearDown() throws Exception{
transaction.rollback();
transaction = null;
} transaction.rollback();
transaction = null;
}
/**
* <b> Method Name </b> testCreateCostCode_2_3 <br><br>
* <b> description </b> tests the cost code creation advertised on
* the Cost Code service
*
* @author rdb
* @since 2.3
*/
public void testCreateCostCode_2_3() {
String testName = "testCreateCostCode_2_3 ";
int testNo = 0;
CostCodeData costCodeDataIML = null;
try {
// valid test case
testNo += 1;
costCodeDataIML = new CostCodeData();
populateEntity(costCodeDataIML, t_Create);
costCodeService.createCostCode_2_3(costCodeDataIML );
passWithNoExceptionRaised(testName, Integer.toString(testNo));
}
catch(Exception ex) {
failWithExceptionRaised(testName, Integer.toString(testNo), ex);
}
}
public void generateTransactionObjectStub() throws Exception, NamingException{
if (ejbContext == null) {
throw new Exception("No successful JNDI lookup was made prior to retrieving an EJB home object");
}
else {
transaction = (UserTransaction) ejbContext.lookup("javax.transaction.UserTransacti on");
}
}


Reply With Quote