Ok, it is as I suspected. The Oracle XA driver just returns bad information here. For DatabaseMetaData#supportsDataDefinitionInTransaction() it returns true. Yet clearly it does not.
I have developed a work around and am working on a fix to allow dialects to override know bad DatabaseMetaData#supportsDataDefinitionInTransaction() implementations much like we have with org.hibernate.dialect.Dialect#performTemporaryTableDDLInIsolation for handling bad DatabaseMetaData#dataDefinitionCausesTransactionCommit() implementations.
The work-around is to specify a custom org.hibernate.hql.spi.MultiTableBulkIdStrategy implementation using the hibernate.hql.bulk_id_strategy setting:
CustomBulkIdDelegate.java
import java.sql.Connection;
import java.sql.SQLWarning;
import java.sql.Statement;
import org.jboss.logging.Logger;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.hql.spi.TemporaryTableBulkIdStrategy;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jdbc.AbstractWork;
import org.hibernate.persister.entity.Queryable;
/**
* @author Steve Ebersole
*/
public class CustomBulkIdDelegate extends TemporaryTableBulkIdStrategy {
privatestaticfinal CoreMessageLogger log = Logger.getMessageLogger( CoreMessageLogger.class, CustomBulkIdDelegate.class.getName() );
@Override
protected void createTempTable(Queryable persister, SessionImplementor session) {
TemporaryTableCreationWork work = new TemporaryTableCreationWork( persister );
// here we always want to (a) create the tables in isolation and (b) do not start a new transaction for the creation
session.getTransactionCoordinator()
.getTransaction()
.createIsolationDelegate()
.delegateWork( work, false );
}
// todo make these protected on TemporaryTableBulkIdStrategy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
privatestatic SqlExceptionHelper.WarningHandler CREATION_WARNING_HANDLER = new SqlExceptionHelper.WarningHandlerLoggingSupport() {
publicboolean doProcess() {
return log.isDebugEnabled();
}
public void prepare(SQLWarning warning) {
log.warningsCreatingTempTable( warning );
}
@Override
protected void logWarning(String description, String message) {
log.debug( description );
log.debug( message );
}
};
privatestatic class TemporaryTableCreationWork extends AbstractWork {
privatefinal Queryable persister;
private TemporaryTableCreationWork(Queryable persister) {
this.persister = persister;
}
@Override
public void execute(Connection connection) {
try {
Statement statement = connection.createStatement();
try {
statement.executeUpdate( persister.getTemporaryIdTableDDL() );
persister.getFactory()
.getServiceRegistry()
.getService( JdbcServices.class )
.getSqlExceptionHelper()
.handleAndClearWarnings( statement, CREATION_WARNING_HANDLER );
}
finally {
try {
statement.close();
}
catch( Throwable ignore ) {
// ignore
}
}
}
catch( Exception e ) {
log.debug( "unable to create temporary id table [" + e.getMessage() + "]" );
}
}
}
}
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
Ok, it is as I suspected. The Oracle XA driver just returns bad information here. For DatabaseMetaData#supportsDataDefinitionInTransaction() it returns true. Yet clearly it does not.
I have developed a work around and am working on a fix to allow dialects to override know bad DatabaseMetaData#supportsDataDefinitionInTransaction() implementations much like we have with org.hibernate.dialect.Dialect#performTemporaryTableDDLInIsolation for handling bad DatabaseMetaData#dataDefinitionCausesTransactionCommit() implementations.
The work-around is to specify a custom org.hibernate.hql.spi.MultiTableBulkIdStrategy implementation using the hibernate.hql.bulk_id_strategy setting: