If all you want is Hibernate/JPA and a database connection pool, pick one that is JTA compatible. I've only just now found Bitronix and it looks great.
Put this in your pom.xml:
<repository>
<id>jboss-repo</id>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<dependency>
<groupId>org.codehaus.btm</groupId>
<artifactId>btm</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<!-- ORCL can't be bothered to update javax.persistence in Maven central but
I hear great things about their new sailboat -->
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.6.Final</version>
<exclusions>
<!-- Javassist does the job -->
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</exclusion>
</exclusions>
</dependency>
Hibernate and the JTA manager will communicate through JNDI (don't get me started), so put a
jndi.properties file on your classpath to enable the bundled minimal implementation:
java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory
Next configure and start the JTA manager and connection pool - see the Bitronix website if you want to do this with property files instead of code:
// Each JVM needs a stable unique identifier for TX recovery
TransactionManagerServices.getConfiguration().setServerId("myServer1234");
// Create the datasource and set the connection pool details
PoolingDataSource datasource = new PoolingDataSource();
datasource.setUniqueName("myDS");
datasource.setMinPoolSize(5);
datasource.setMaxPoolSize(25);
datasource.setPreparedStatementCacheSize(50);
// If you use Hibernate's hbm2ddl.auto mode, on startup SchemaExport executes
// connection.setAutoCommit(true) to export DDL. This is a non-XA transaction.
// Alternatively, wrap UserTransaction.begin() and commit() around your Hibernate
// startup code.
datasource.setAllowLocalTransactions(true);
// This is for H2 DBMS, which I really like for small scale use
datasource.setClassName("org.h2.jdbcx.JdbcDataSource");
datasource.getDriverProperties().put("URL", "jdbc:h2:mem:myTemporaryDB");
// H2 doesn't need a password for temporary in-memory databases
//datasource.getDriverProperties().setProperty("user", "scott");
//datasource.getDriverProperties().setProperty("password", "tiger");
// Create pool, bind datasource to JNDI
datasource.init();
Now set the datasource name for JNDI lookup in JPA's META-INF/persistence.xml and configure how
Hibernate should lookup the transaction manager:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myPU">
<jta-data-source>myDS</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.BTMTransactionManagerLookup"/>
<property name="hibernate.hbm2ddl.auto"
value="create"/>
</properties>
</persistence-unit>
</persistence>
Finally, start JPA and write units of work with EntityManagers:
Context ctx = new InitialContext();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU");
UserTransaction tx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
tx.begin();
EntityManager em = emf.createEntityManager();
em.persist();
em.createQuery();
tx.commit();
That's neat. Now can we get rid of JNDI and have someone competent redesign the JTA API, please?
(I've tried Emmanuel's guide for standalone usage of JBoss TS but the dependencies are just too scary. I don't trust a transaction manager runtime that depends on a diagram drawing library or a test coverage tool. No, it's not fixed in the latest version. If the implementation code looks like the build setup...)

