PROTOTYPE - Transaction DataSource in a POJO environment
adrian.brock May 3, 2005 10:34 AMI've created a simple prototype that uses the MC to bootstrap
a transactional datasource inside a pojo environment.
It uses in memory hypersonic, but this can easily be changed with
the MCF properties.
You can find the simple code in
aspects/src/tests/org/jboss/test/aspects/microcontainer/test/POJOEnvironmentTestCase
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.test.aspects.microcontainer.test;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import org.jboss.kernel.Kernel;
import org.jboss.kernel.plugins.deployment.xml.XMLKernelDeployer;
/**
* POJO Environment tests
*
* @TODO XMLKernelDeployer -> BeanXMLDeployer
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision: 1.1 $
*/
public class POJOEnvironmentTestCase extends AbstractMicroContainerTest
{
XMLKernelDeployer deployer;
public POJOEnvironmentTestCase(String name)
{
super(name);
}
protected void setUp() throws Exception
{
super.setUp();
try
{
Kernel kernel = bootstrap();
deployer = new XMLKernelDeployer(kernel);
URL bootstrap = getClass().getResource("/bootstrap.xml");
if (bootstrap == null)
throw new RuntimeException("Cannot find bootstrap.xml");
deployer.deploy(bootstrap);
deployer.validate();
}
catch (Exception e)
{
throw e;
}
catch (Throwable t)
{
throw new RuntimeException(t);
}
}
public void testTxDataSource() throws Throwable
{
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/DefaultDS");
TransactionManager tm = (TransactionManager) ctx.lookup("java:/TransactionManager");
log.info("Creating table");
Connection c = ds.getConnection();
try
{
Statement s = c.createStatement();
s.execute("create table test (key integer, value char(50))");
}
finally
{
c.close();
}
log.info("Perform an insert but do a rollback");
tm.begin();
try
{
c = ds.getConnection();
try
{
Statement s = c.createStatement();
s.execute("insert into test (key, value) values(1, 'Hello')");
}
finally
{
c.close();
}
}
finally
{
tm.rollback();
}
log.info("The row count should be zero");
c = ds.getConnection();
try
{
Statement s = c.createStatement();
ResultSet r = s.executeQuery("select count(*) from test");
if (r.next())
{
assertEquals(0, r.getInt(1));
}
else
fail("Should not be here");
}
finally
{
c.close();
}
log.info("Do an insert and this time commit");
tm.begin();
try
{
c = ds.getConnection();
try
{
Statement s = c.createStatement();
s.execute("insert into test (key, value) values(1, 'Goodbye')");
}
finally
{
c.close();
}
}
finally
{
tm.commit();
}
log.info("We should be able to retrieve the value");
c = ds.getConnection();
try
{
Statement s = c.createStatement();
ResultSet r = s.executeQuery("select value from test where key=1");
if (r.next())
{
assertEquals("Goodbye", r.getString(1));
}
else
fail("Should not be here");
}
finally
{
c.close();
}
}
protected void configureLoggingAfterBootstrap()
{
enableTrace("org.jboss.tm");
}
}
The "helper" classes are in
aspects/src/tests/org/jboss/test/aspects/microcontainer/support/pojo
and two configuration files are required
from aspects/src/resources/tests/pojo
jndi.propertes - (creates an in memory initial context)
and the bootstrap config
<?xml version="1.0" encoding="UTF-8"?> <deployment> <!-- JNDI --> <bean name="Naming" class="org.jboss.test.aspects.microcontainer.support.pojo.POJONamingServer"/> <!-- TransactionManager --> <bean name="TransactionManager" class="org.jboss.tm.TxManager"> <constructor factoryClass="org.jboss.test.aspects.microcontainer.support.pojo.TransactionManagerFactory" factoryMethod="getTransactionManager" /> </bean> <bean name="TMBinding" class="org.jboss.test.aspects.microcontainer.support.pojo.JNDIBinding"> <constructor> <parameter>java:/TransactionManager</parameter> <parameter><inject bean="TransactionManager"/></parameter> </constructor> </bean> <!-- JCA CCM --> <bean name="CachedConnectionManager" class="org.jboss.resource.connectionmanager.CachedConnectionManager"> </bean> <!-- ManagedConnectionFactory configured to use in memory hypersonic --> <bean name="ManagedConnectionFactory" class="org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory"> <property name="driverClass">org.hsqldb.jdbcDriver</property> <property name="connectionURL">jdbc:hsqldb:.</property> <property name="userName">sa</property> </bean> <!-- Pooling parameters --> <bean name="PoolParams" class="org.jboss.resource.connectionmanager.InternalManagedConnectionPool$PoolParams"> </bean> <!-- FIXME: API requires a logger --> <bean name="Log" class="org.jboss.logging.Logger"> <constructor factoryClass="org.jboss.logging.Logger" factoryMethod="getLogger"> <parameter>org.jboss.resource.connectionmanager.JBossManagedConnectionPool</parameter> </constructor> </bean> <!-- The pool --> <bean name="Pool" class="org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool"> <constructor> <parameter><inject bean="ManagedConnectionFactory"/></parameter> <parameter><inject bean="PoolParams"/></parameter> <parameter>false</parameter> <parameter><inject bean="Log"/></parameter> </constructor> </bean> <!-- The connection manager behind the DataSource --> <bean name="ConnectionManager" class="org.jboss.test.aspects.microcontainer.support.pojo.POJOConnectionManager"> <constructor> <parameter><inject bean="CachedConnectionManager"/></parameter> <parameter><inject bean="Pool"/></parameter> <parameter><inject bean="TransactionManager"/></parameter> </constructor> <property name="localTransactions">true</property> <property name="trackConnectionByTx">true</property> </bean> <bean name="DataSource" class="org.jboss.resource.adapter.jdbc.WrapperDataSource"> <constructor factoryMethod="getFactory"> <factory value="ConnectionManager"/> </constructor> </bean> <bean name="DSBinding" class="org.jboss.test.aspects.microcontainer.support.pojo.JNDIBinding"> <constructor> <parameter>java:/DefaultDS</parameter> <parameter><inject bean="DataSource"/></parameter> </constructor> </bean> </deployment>