Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Bitronix Transaction Manager
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<h1>Integrating BTM with Hibernate</h1> <p>Hibernate can be integrated straight with any JTA transaction manager. These instructions have been verified against BTM 2.1.1 and Hibernate 3.6.3.Final.</p> <p>The biggest added value (omitting the fact that you can use Hibernate and two databases) is Hibernate's <a href="http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/session-configuration.html#configuration-j2ee-currentsession">Current Session context management with JTA</a>. You do not have to take care about opening nor closing <code>Session</code> as Hibernate will automatically bind them to the JTA transaction's lifecycle. You just have to make sure JTA transactions are properly started and ended.</p> <table class="wysiwyg-macro" data-macro-name="info" data-macro-parameters="title=JPA, Hibernate and BTM" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2luZm86dGl0bGU9SlBBLCBIaWJlcm5hdGUgYW5kIEJUTX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>The example discussed here uses the Hibernate API but the JPA API could be used as well. You just need to use the EntityManager but the same configuration applies.</p></td></tr></table> <h4>Contents</h4> <img class="editor-inline-macro" src="/plugins/servlet/confluence/placeholder/macro?definition=e3RvYzptYXhMZXZlbD0zfG1pbkxldmVsPTJ9&locale=en_GB&version=2" data-macro-name="toc" data-macro-parameters="maxLevel=3|minLevel=2"> <h2>JTA datasources</h2> <p>Hibernate cannot directly create a BTM <code>PoolingDataSource</code>. You will have to create them yourself (either via the API or the Resource Loader).</p> <h3>Setting up the BTM JNDI server</h3> <p>You have to bind the datasources and the transaction manager to some JNDI server. You can use any one you wish, but BTM 2.x.x ships with one you might find more convenient to use.</p> <p>It is very easy to use it in a standalone J2SE application. Just create a <code>jndi.properties</code> file at the root of your classpath. It should only contain this line:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory </pre></td></tr></table> <p>You can now just create a <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/naming/InitialContext.html">InitialContext</a> with the no-args constructor to have access to it.</p> <table class="wysiwyg-macro" data-macro-name="info" data-macro-parameters="title=Multiple JNDI providers" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2luZm86dGl0bGU9TXVsdGlwbGUgSk5ESSBwcm92aWRlcnN9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>If you are running your application in a context in which there already is a JNDI provider installed (for instance in a web application) you can tell Hibernate to perform lookups in a specific JNDI environment instead by setting the <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#d0e1858">hibernate.jndi.class</a> property to <code>bitronix.tm.jndi.BitronixInitialContextFactory</code> in Hibernate's configuration instead.</p></td></tr></table> <h3>API way: Creating the datasources</h3> <p>As you can expect, you will need to create one <code>PoolingDataSource</code> per database. Say that you want to use two Embedded Derby databases, and configure them via the BTM API. Here is what your code would look like:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> PoolingDataSource ds1 = new PoolingDataSource(); ds1.setUniqueName("jdbc/testDS1"); ds1.setClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); ds1.setMaxPoolSize(3); ds1.getDriverProperties().put("databaseName", "users1"); ds1.init(); PoolingDataSource ds2 = new PoolingDataSource(); ds2.setUniqueName("jdbc/testDS2"); ds2.setClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); ds2.setMaxPoolSize(3); ds2.getDriverProperties().put("databaseName", "users2"); ds2.init(); </pre></td></tr></table> <table class="wysiwyg-macro" data-macro-name="tip" data-macro-parameters="title=Datasource's unique name and JNDI location correspondence" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3RpcDp0aXRsZT1EYXRhc291cmNlJ3MgdW5pcXVlIG5hbWUgYW5kIEpOREkgbG9jYXRpb24gY29ycmVzcG9uZGVuY2V9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>The BTM JNDI provider will automatically bind the datasources under their unique name. In this case, you can look up jdbc/testDS1 or jdbc/testDS2 as soon as the transaction manager started without having anything else to configure.</p></td></tr></table> <h3>Resource Loader way: Creating the datasources</h3> <p>You can use BTM's Resource Loader instead of the BTM API. It is usually a good idea when you want to create a fully standalone application as you can get rid of the datasources creation and shutdown code.</p> <p>Create a <code>datasources.properties</code> file in the current directory containing these properties:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> resource.ds1.className=org.apache.derby.jdbc.EmbeddedXADataSource resource.ds1.uniqueName=jdbc/testDS1 resource.ds1.maxPoolSize=3 resource.ds1.driverProperties.databaseName=users1 resource.ds2.className=org.apache.derby.jdbc.EmbeddedXADataSource resource.ds2.uniqueName=jdbc/testDS2 resource.ds2.maxPoolSize=3 resource.ds2.driverProperties.databaseName=users2 </pre></td></tr></table> <table class="wysiwyg-macro" data-macro-name="tip" data-macro-parameters="title=Resource Loader and JNDI binding" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3RpcDp0aXRsZT1SZXNvdXJjZSBMb2FkZXIgYW5kIEpOREkgYmluZGluZ30&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>As with the API, the datasources will be available in JNDI under their unique name.</p></td></tr></table> <p>In your application code, you will have to configure BTM to use the resource loader:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> TransactionManagerServices.getConfiguration().setResourceConfigurationFilename("./datasources.properties"); userTransaction = TransactionManagerServices.getTransactionManager(); </pre></td></tr></table> <p>This has the exact same behavior as creating the <code>PoolingDataSource</code> objects yourself. It is just more convenient.</p> <h2>Hibernate Session factories</h2> <p>You need to configure exactly one <code>SessionFactory</code> per datasource.</p> <h3>Datasource JNDI location</h3> <p>You have to tell Hibernate where to get the BTM datasource via JNDI. Add a <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#d0e1858">connection.datasource</a> property and set its value to the JNDI location of your datasource:</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="xml" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6eG1sfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <property name="connection.datasource">jdbc/testDS1</property> </pre></td></tr></table> <h3>Current session context</h3> <p>You have to set <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-misc-properties">current_session_context_class</a> to <code>jta</code>.</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="xml" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6eG1sfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <property name="current_session_context_class">jta</property> </pre></td></tr></table> <h3>Transaction factory class</h3> <p>You have to set <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-transaction-properties">transaction.factory_class</a> to <a href="http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/transaction/JTATransactionFactory.html">org.hibernate.transaction.JTATransactionFactory</a>.</p> <table class="wysiwyg-macro" data-macro-name="note" data-macro-parameters="title=JPA / EJB3 API" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e25vdGU6dGl0bGU9SlBBIC8gRUpCMyBBUEl9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"> <p>When you use Hibernate via the JPA / EJB3 API (also known as <em>Hibernate EntityManager</em>) you should not set the <code>transaction.factory_class</code> property as the <code>Ejb3Configuration</code> class will configure a special one which is JTA compatible if you configure your <code>PersistenceUnit</code>'s transaction type to JTA.</p></td></tr></table> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="xml" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6eG1sfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property> </pre></td></tr></table> <h3>Transaction manager lookup class</h3> <p>You have to set <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-transaction-properties">transaction.manager_lookup_class</a> to an implementation of <a href="http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/transaction/TransactionManagerLookup.html">TransactionManagerLookup</a>. Hibernate ships with one that can lookup BTM since version 3.3.</p> <p>add this property to your config to use it:</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="xml" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6eG1sfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <property name="transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup</property> </pre></td></tr></table> <table class="wysiwyg-macro" data-macro-name="note" data-macro-parameters="title=BTMTransactionManagerLookup and JNDI" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e25vdGU6dGl0bGU9QlRNVHJhbnNhY3Rpb25NYW5hZ2VyTG9va3VwIGFuZCBKTkRJfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"> <p>The BTMTransactionManagerLookup implementation which ships with Hibernate has a limitation regarding JNDI lookup of the transaction manager. If you're going to use it within an application server that already contains a JNDI server you might encounter problems.<br /> An improved version which solves that issue has been submitted to the Hibernate project, see: <a class="external-link" href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-3739" rel="nofollow">http://opensource.atlassian.com/projects/hibernate/browse/HHH-3739</a><br /> Also remember to change the <a class="confluence-link" href="/display/BTM/Configuration2x#Configuration2x-Configuration2x-Transactionenginesettings" data-anchor="Configuration2x-Transactionenginesettings" data-linked-resource-id="183074829" data-linked-resource-type="page" data-linked-resource-default-alias="Configuration2x#Configuration2x-Transactionenginesettings" data-base-url="http://docs.codehaus.org">jndiUserTransactionName</a> value to something else, for instance: <em><strong>bitronixTransactionManager</strong></em>.</p></td></tr></table> <h3>SessionFactory XML configuration files</h3> <p>Here is what the <code>hibernate_testDS1.cfg.xml</code> file will look like for the first datasource. Some other mandatory properties also have to be added, like the <code>dialect</code>, <code>cache.provider_class</code> and of course the required object mappings.</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="XML" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6WE1MfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.datasource">jdbc/testDS1</property> <property name="connection.release_mode">after_statement</property> <property name="current_session_context_class">jta</property> <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property> <property name="transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup</property> <property name="dialect">org.hibernate.dialect.DerbyDialect</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="show_sql">true</property> <mapping resource="bitronix/examples/hibernate/entities/User.hbm.xml"/> </session-factory> </hibernate-configuration> </pre></td></tr></table> <p>And here is the <code>hibernate_testDS2.cfg.xml</code> for the second datasource:</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="XML" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6WE1MfQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.datasource">jdbc/testDS2</property> <property name="connection.release_mode">after_statement</property> <property name="current_session_context_class">jta</property> <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property> <property name="transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup</property> <property name="dialect">org.hibernate.dialect.DerbyDialect</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="show_sql">true</property> <mapping resource="bitronix/examples/hibernate/entities/User.hbm.xml"/> </session-factory> </hibernate-configuration> </pre></td></tr></table> <h2>End result</h2> <p>Now that Hibernate and BTM are properly configured, you can simply use the JTA and Hibernate APIs in your application.</p> <h3>Application code</h3> <p>Here is what your code will look like when you want to update the content of both databases atomically:</p> <table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> for (int i=0; i<10 ;i++) { System.out.println("Iteration #" + (i+1)); userTransaction.setTransactionTimeout(60); userTransaction.begin(); try { System.out.println("*** DB1 ***"); persistUser(sf1, "user"); listUsers(sf1); System.out.println("*** DB2 ***"); persistUser(sf2, "user"); listUsers(sf2); userTransaction.commit(); } catch (Exception ex) { ex.printStackTrace(); userTransaction.rollback(); } } </pre></td></tr></table> <p>Say that <code>persistUser()</code> creates a new user, in <em>no way</em> will a user be created in one database and not in the other.</p> <h2>Download</h2> <p>You can download a sample runnable application putting these explanations in practice. It contains all the code that has been skipped for clarity in this page. Both the API and Resource Loader ways are implemented so you can try both and see which one you prefer.</p> <p>You can download this demo here: <a href="http://www.bitronix.be/examples/HibernateBTM2x.zip">HibernateBTM2x.zip</a>.</p> <p>There is an ant <strong>build.xml</strong> file included as well as a the necessary batch and shell scripts required to run the application from Windows or Unix.</p> <p>Before you run the application, you have to create the Derby database. Just run the included <strong>derby-create.sh</strong> or <strong>derby-create.bat</strong> script to do so, it will create two directories called <strong>users1</strong> and <strong>users2</strong>. Then you can start the demo by either running <strong>run_api.sh</strong> or <strong>run_api.bat</strong> for the API version, <strong>run_rl.sh</strong> or <strong>run_rl.bat</strong> for the Resource Loader version.</p> <p>Here is the list of JAR files with version required to run this demo. They're all included in the downloadable ZIP file.</p> <table class="confluenceTable"><tbody> <tr> <th class="confluenceTh"><p> JAR name </p></th> <th class="confluenceTh"><p> Version </p></th> </tr> <tr> <td class="confluenceTd"><p> btm-2.1.1.jar </p></td> <td class="confluenceTd"><p> BTM 2.1.1 </p></td> </tr> <tr> <td class="confluenceTd"><p> geronimo-jta_1.1_spec-1.1.1.jar </p></td> <td class="confluenceTd"><p> BTM 2.1.1 </p></td> </tr> <tr> <td class="confluenceTd"><p> slf4j-api-1.6.1.jar </p></td> <td class="confluenceTd"><p> SLF4J 1.6.1 </p></td> </tr> <tr> <td class="confluenceTd"><p> slf4j-jdk14-1.6.1.jar </p></td> <td class="confluenceTd"><p> SLF4J 1.6.1 </p></td> </tr> <tr> <td class="confluenceTd"><p> derby-10.3.1.4.jar </p></td> <td class="confluenceTd"><p> Derby 10.3.1.4 </p></td> </tr> <tr> <td class="confluenceTd"><p> derbytools-10.3.1.4.jar </p></td> <td class="confluenceTd"><p> Derby 10.3.1.4 </p></td> </tr> <tr> <td class="confluenceTd"><p> antlr-2.7.6.jar </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> <tr> <td class="confluenceTd"><p> hibernate-jpa-2.0-api-1.0.0.Final.jar </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> <tr> <td class="confluenceTd"><p> javassist-3.12.0.GA </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> <tr> <td class="confluenceTd"><p> commons-collections-3.1.jar </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> <tr> <td class="confluenceTd"><p> dom4j-1.6.1.jar </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> <tr> <td class="confluenceTd"><p> hibernate3.jar </p></td> <td class="confluenceTd"><p> Hibernate 3.6.3.Final </p></td> </tr> </tbody></table> <p><img class="confluence-embedded-image confluence-external-resource" src="http://www.bitronix.be/images/shim.gif" data-image-src="http://www.bitronix.be/images/shim.gif"></p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced