org.hibernate.transaction
public class: JTATransactionFactory [javadoc |
source]
java.lang.Object
org.hibernate.transaction.JTATransactionFactory
All Implemented Interfaces:
TransactionFactory
Factory for
JTATransaction instances.
To be completely accurate to the JTA spec, JTA implementations should
publish their contextual
UserTransaction reference into JNDI.
However, in practice there are quite a few
stand-alone
implementations intended for use outside of J2EE/JEE containers and
which therefore do not publish their
UserTransaction references
into JNDI but which otherwise follow the aspects of the JTA specification.
This
TransactionFactory implementation can support both models.
For complete JTA implementations (including dependence on JNDI), the
UserTransaction reference is obtained by a call to
#resolveInitialContext . Hibernate will then attempt to locate the
UserTransaction within this resolved
InitialContext based on the namespace returned by
#resolveUserTransactionName .
For the so-called
stand-alone implementations, we do not care at
all about the JNDI aspects just described. Here, the implementation would
have a specific manner to obtain a reference to its contextual
UserTransaction ; usually this would be a static code reference, but
again it varies. Anyway, for each implementation the integration would need
to override the
#getUserTransaction method and return the appropriate
thing.
- author:
Gavin - King
- author:
Steve - Ebersole
- author:
Les - Hazlewood
| Field Summary |
|---|
| public static final String | DEFAULT_USER_TRANSACTION_NAME | |
| protected InitialContext | initialContext | |
| protected String | userTransactionName | |
| Method from org.hibernate.transaction.JTATransactionFactory Summary: |
|---|
|
areCallbacksLocalToHibernateTransactions, configure, createTransaction, getDefaultReleaseMode, getInitialContext, getUserTransaction, getUserTransactionName, isTransactionInProgress, isTransactionManagerRequired, resolveInitialContext, resolveUserTransactionName |
| Method from org.hibernate.transaction.JTATransactionFactory Detail: |
public boolean areCallbacksLocalToHibernateTransactions() {
return false;
}
|
public void configure(Properties props) throws HibernateException {
this.initialContext = resolveInitialContext( props );
this.userTransactionName = resolveUserTransactionName( props );
log.trace( "Configured JTATransactionFactory to use [{}] for UserTransaction JDNI namespace", userTransactionName );
}
|
public Transaction createTransaction(JDBCContext jdbcContext,
Context transactionContext) throws HibernateException {
UserTransaction ut = getUserTransaction();
return new JTATransaction( ut, jdbcContext, transactionContext );
}
|
public ConnectionReleaseMode getDefaultReleaseMode() {
return ConnectionReleaseMode.AFTER_STATEMENT;
}
|
protected InitialContext getInitialContext() {
return initialContext;
}
Getter for property 'initialContext'. |
protected UserTransaction getUserTransaction() {
log.trace( "Attempting to locate UserTransaction via JNDI [{}]", getUserTransactionName() );
try {
UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( getUserTransactionName() );
if ( ut == null ) {
throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + getUserTransactionName() +"]" );
}
log.trace( "Obtained UserTransaction" );
return ut;
}
catch ( NamingException ne ) {
throw new TransactionException( "Could not find UserTransaction in JNDI [" + getUserTransaction() + "]", ne );
}
}
|
protected String getUserTransactionName() {
return userTransactionName;
}
Getter for property 'userTransactionName'.
The algorithm here is |
public boolean isTransactionInProgress(JDBCContext jdbcContext,
Context transactionContext,
Transaction transaction) {
try {
// Essentially:
// 1) If we have a local (Hibernate) transaction in progress
// and it already has the UserTransaction cached, use that
// UserTransaction to determine the status.
// 2) If a transaction manager has been located, use
// that transaction manager to determine the status.
// 3) Finally, as the last resort, try to lookup the
// UserTransaction via JNDI and use that to determine the
// status.
if ( transaction != null ) {
UserTransaction ut = ( ( JTATransaction ) transaction ).getUserTransaction();
if ( ut != null ) {
return JTAHelper.isInProgress( ut.getStatus() );
}
}
if ( jdbcContext.getFactory().getTransactionManager() != null ) {
return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
}
else {
UserTransaction ut = getUserTransaction();
return ut != null && JTAHelper.isInProgress( ut.getStatus() );
}
}
catch ( SystemException se ) {
throw new TransactionException( "Unable to check transaction status", se );
}
}
|
public boolean isTransactionManagerRequired() {
return false;
}
|
protected final InitialContext resolveInitialContext(Properties properties) {
try {
return NamingHelper.getInitialContext( properties );
}
catch ( NamingException ne ) {
throw new HibernateException( "Could not obtain initial context", ne );
}
}
Given the lot of Hibernate configuration properties, resolve appropriate
reference to JNDI InitialContext .
In general, the properties in which we are interested here all begin with
hibernate.jndi. Especially important depending on your
environment are hibernate.jndi.url and
hibernate.jndi.class |
protected final String resolveUserTransactionName(Properties properties) {
String utName = properties.getProperty( Environment.USER_TRANSACTION );
if ( utName == null ) {
TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
if ( lookup != null ) {
utName = lookup.getUserTransactionName();
}
}
return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
}
|