It is a simple blueprint application that shows and updates the content of two Derby databases in a single atomic transaction controlled via the JTA API.
Download the sample application here: In the ZIP file you'll find:
package com.atomikos.examples.hibernate;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.UserTransaction;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.atomikos.examples.hibernate.entities.User;
import com.atomikos.jdbc.SimpleDataSourceBean;
public class Main {
private static UserTransaction userTransaction;
private static SimpleDataSourceBean dataSource1;
private static SimpleDataSourceBean dataSource2;
public static void main(String[] args) throws Exception {
initDataSources();
initTransactionManager();
SessionFactory sf1 = new Configuration().
configure("/hibernate1.cfg.xml").buildSessionFactory();
SessionFactory sf2 = new Configuration().
configure("/hibernate2.cfg.xml").buildSessionFactory();
userTransaction.setTransactionTimeout(60);
userTransaction.begin();
try {
System.out.println("*** DB1 ***");
doWork(sf1, "user");
System.out.println("*** DB2 ***");
doWork(sf2, "user");
userTransaction.commit();
}
catch (Exception ex) {
ex.printStackTrace();
userTransaction.rollback();
}
sf1.close();
sf2.close();
dataSource1.close();
dataSource2.close();
System.out.println("Both databases updated successfully");
}
/**
* Perform some work. In this scenario, we get a session from the specified
* SessionFactory then we create a new user with the specified username
* then list all users.
*/
private static void doWork(SessionFactory sf, String username) {
Session session = sf.getCurrentSession();
persistUser(session, username);
listUsers(session);
session.close();
}
/**
* Dump all users to stdout using the specified Hibernate session.
*/
private static void listUsers(Session session) {
List users = session.createQuery("from User").list();
for (int i=0; i<users.size() ;i++) {
User user = (User) users.get(i);
System.out.println(user.toString());
}
}
/**
* Create a new user with specified name using the specified Hibernate session.
*/
private static void persistUser(Session session, String userName) {
User u = new User();
u.setName(userName);
session.save(u);
}
/**
* Initialize the transaction manager.
*/
private static void initTransactionManager() {
userTransaction = new com.atomikos.icatch.jta.UserTransactionImp();
}
/**
* Create the 2 datasources and bind them into the embedded JNDI server.
*/
private static void initDataSources() throws NamingException {
Context ctx = new InitialContext();
dataSource1 = getDataSource_db1();
ctx.rebind("testDS1", dataSource1);
dataSource2 = getDataSource_db2();
ctx.rebind("testDS2", dataSource2);
ctx.close();
}
/**
* Create the first datasource.
*/
private static SimpleDataSourceBean getDataSource_db1() {
SimpleDataSourceBean ds = new SimpleDataSourceBean();
ds.setUniqueResourceName("derby1");
ds.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
ds.setXaDataSourceProperties("databaseName=users1");
ds.setConnectionPoolSize(3);
return ds;
}
/**
* Create the second datasource.
*/
private static SimpleDataSourceBean getDataSource_db2() {
SimpleDataSourceBean ds = new SimpleDataSourceBean();
ds.setUniqueResourceName("derby2");
ds.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
ds.setXaDataSourceProperties("databaseName=users2");
ds.setConnectionPoolSize(3);
return ds;
}
}
package com.atomikos.examples.hibernate.entities;
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "a User(id=" + id + ", name=" + name + ")";
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.atomikos.examples.hibernate.entities">
<class name="User" table="`USERS`">
<id name="id">
<generator class="identity"/>
</id>
<property name="name" not-null="true" column="`NAME`"/>
</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">testDS1</property>
<property name="dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="current_session_context_class">jta</property>
<property name="transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="connection.release_mode">auto</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true</property>
<mapping resource="com/atomikos/examples/hibernate/entities/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">testDS2</property>
<property name="dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="current_session_context_class">jta</property>
<property name="transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="connection.release_mode">auto</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true</property>
<mapping resource="com/atomikos/examples/hibernate/entities/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory com.atomikos.icatch.automatic_resource_registration=true com.atomikos.icatch.console_log_level=DEBUG
java.naming.factory.initial=org.apache.naming.java.javaURLContextFactory
| JAR name | Source |
|---|---|
| antlr-2.7.6.jar | Hibernate 3.2.1 |
| asm.jar | Hibernate 3.2.1 |
| cglib-2.1.3.jar | Hibernate 3.2.1 |
| commons-collections-2.1.1.jar | Hibernate 3.2.1 |
| commons-logging-1.0.4.jar | Hibernate 3.2.1 |
| dom4j-1.6.1.jar | Hibernate 3.2.1 |
| hibernate3.jar | Hibernate 3.2.1 |
| jta.jar | Hibernate 3.2.1 |
| naming-factory.jar | Apache Tomcat 5.5.23 |
| naming-resources.jar | Apache Tomcat 5.5.23 |
| derby-10.2.2.0.jar | Derby 10.2.2.0 |
| derbytools-10.2.2.0.jar | Derby 10.2.2.0 |
| atomikos-util.jar | TransactionsEssentials 3.1.5 |
| transactions-api.jar | TransactionsEssentials 3.1.5 |
| transactions-hibernate3.jar | TransactionsEssentials 3.1.5 |
| transactions-jta.jar | TransactionsEssentials 3.1.5 |
| transactions.jar | TransactionsEssentials 3.1.5 |