= Hibernate
:index-group: Unrevised
:jbake-date: 2018-12-05
:jbake-type: page
:jbake-status: published

= Sample persistence.xml

For a unit called "movie-unit" using two datasources called
"movieDatabase" and "movieDatabaseUnmanaged" the following
`persistence.xml` would work.

[source,xml]
----
<persistence version="1.0"
       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_1_0.xsd">

  <persistence-unit name="movie-unit">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>movieDatabase</jta-data-source>
    <non-jta-data-source>movieDatabaseUnmanaged</non-jta-data-source>

    <properties>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      <property name="hibernate.transaction.manager_lookup_class"
                value="org.apache.openejb.hibernate.TransactionManagerLookup"/>
    </properties>
  </persistence-unit>
</persistence>
----

Note that as of OpenEJB 3.1 you do not need to set the
`hibernate.transaction.manager_lookup_class` as it will be set for you
automatically and will overwrite any "org.hibernate.transaction."
strategy class already set while leaving any custom strategy class you
may have implemented untouched.

The result is that you can leave your
`hibernate.transaction.manager_lookup_class` property configured to your
production environment and OpenEJB will update it just for the scope
testing. On the other hand if you have implemented a custom
`org.hibernate.transaction.TransactionManagerLookup` strategy it will
always be used and never replaced by OpenEJB.

Note that if you need more functionality in this area we are always
happy to add it.

== Not using OpenEJB in production?

If you're using OpenEJB 3.0 which does not support the dynamic switching
of the `hibernate.transaction.manager_lookup_class` this is one way to
achieve it.

A custom implementation of Hibernate's _TransactionManagerLookup_
strategy like the following will do the trick. This
"DynamicTransactionManagerLookup" class can be packed in your jar and
deployed with your app.

[source,java]
----
import org.hibernate.HibernateException;
import org.hibernate.transaction.TransactionManagerLookup;
import jakarta.transaction.TransactionManager;
import java.util.Properties;

public class DynamicTransactionManagerLookup implements TransactionManagerLookup {

    private TransactionManagerLookup impl;

    public DynamicTransactionManagerLookup() {
        String[] strategies = {
                "org.apache.openejb.hibernate.TransactionManagerLookup",
                "org.hibernate.transaction.JBossTransactionManagerLookup"
        };

        for (String className : strategies) {
            try {
                Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
                impl = (TransactionManagerLookup) clazz.newInstance();
                break;
            } catch (Exception e) {
            }
        }

        if (impl == null) throw new IllegalStateException("No TransactionManagerLookup available");
    }

    public TransactionManager getTransactionManager(Properties properties) throws HibernateException {
        return impl.getTransactionManager(properties);
    }

    public String getUserTransactionName() {
        return impl.getUserTransactionName();
    }
}
----

Then set the Hibernate specific configuration property
_hibernate.transaction.manager_lookup_class_ to the name of the factory
that you just created.
