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>