Author: steve.ebersole(a)jboss.com
Date: 2006-12-06 08:04:31 -0500 (Wed, 06 Dec 2006)
New Revision: 10936
Modified:
trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java
trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java
trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
trunk/Hibernate3/test/org/hibernate/test/TestCase.java
trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java
Log:
HHH-2221 : MySQL and temporary table creation
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-12-05 22:43:52 UTC
(rev 10935)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Cache71Dialect.java 2006-12-06 13:04:31 UTC
(rev 10936)
@@ -451,8 +451,8 @@
return "create global temporary table";
}
- public boolean performTemporaryTableDDLInIsolation() {
- return false;
+ public Boolean performTemporaryTableDDLInIsolation() {
+ return Boolean.FALSE;
}
public String getCreateTemporaryTablePostfix() {
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-12-05 22:43:52 UTC (rev
10935)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-12-06 13:04:31 UTC (rev
10936)
@@ -943,14 +943,30 @@
}
/**
- * Does the dialect require that temporary table DDL statements
- * occur in isolation from other statements?
- * todo : perhaps have this return java.lang.Boolean instead where null means to use the
value returned by the driver.
- *
- * @return
+ * Does the dialect require that temporary table DDL statements occur in
+ * isolation from other statements? This would be the case if the creation
+ * would cause any current transaction to get committed implicitly.
+ * <p/>
+ * JDBC defines a standard way to query for this information via the
+ * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}
+ * method. However, that does not distinguish between temporary table
+ * DDL and other forms of DDL; MySQL, for example, reports DDL causing a
+ * transaction commit via its driver, even though that is not the case for
+ * temporary table DDL.
+ * <p/>
+ * Possible return values and their meanings:<ul>
+ * <li>{@link Boolean#TRUE} - Unequivocally, perform the temporary table DDL
+ * in isolation.</li>
+ * <li>{@link Boolean#FALSE} - Unequivocally, do <b>not</b> perform
the
+ * temporary table DDL in isolation.</li>
+ * <li><i>null</i> - defer to the JDBC driver response in regards to
+ * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}</li>
+ * </ul>
+ *
+ * @return see the result matrix above.
*/
- public boolean performTemporaryTableDDLInIsolation() {
- return false;
+ public Boolean performTemporaryTableDDLInIsolation() {
+ return null;
}
/**
Modified: trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java 2006-12-05 22:43:52 UTC
(rev 10935)
+++ trunk/Hibernate3/src/org/hibernate/dialect/MySQLDialect.java 2006-12-06 13:04:31 UTC
(rev 10936)
@@ -324,4 +324,8 @@
public boolean supportsRowValueConstructorSyntax() {
return true;
}
+
+ public Boolean performTemporaryTableDDLInIsolation() {
+ return Boolean.FALSE;
+ }
}
\ No newline at end of file
Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
---
trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2006-12-05
22:43:52 UTC (rev 10935)
+++
trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2006-12-06
13:04:31 UTC (rev 10936)
@@ -130,7 +130,7 @@
}
}
};
- if ( getFactory().getSettings().isDataDefinitionImplicitCommit() ||
getFactory().getDialect().performTemporaryTableDDLInIsolation() ) {
+ if ( shouldIsolateTemporaryTableDDL() ) {
if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
Isolater.doIsolatedWork( work, session );
}
@@ -168,7 +168,8 @@
}
}
};
- if ( getFactory().getSettings().isDataDefinitionImplicitCommit() ||
getFactory().getDialect().performTemporaryTableDDLInIsolation() ) {
+
+ if ( shouldIsolateTemporaryTableDDL() ) {
if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
Isolater.doIsolatedWork( work, session );
}
@@ -213,4 +214,14 @@
( ( EventSource ) session ).getActionQueue().addAction( action );
}
}
+
+ protected boolean shouldIsolateTemporaryTableDDL() {
+ Boolean dialectVote = getFactory().getDialect().performTemporaryTableDDLInIsolation();
+ if ( dialectVote != null ) {
+ return dialectVote.booleanValue();
+ }
+ else {
+ return getFactory().getSettings().isDataDefinitionImplicitCommit();
+ }
+ }
}
Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-12-05 22:43:52 UTC (rev
10935)
+++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-12-06 13:04:31 UTC (rev
10936)
@@ -624,6 +624,11 @@
return true;
}
+ protected boolean supportsSubqueryOnMutatingTable() {
+ // I only know of MySQL having this limitation...
+ return dialectIsNot( MySQLDialect.class );
+ }
+
private boolean dialectIs(Class dialectClass) {
return dialectClass.isInstance( getDialect() );
}
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java 2006-12-05
22:43:52 UTC (rev 10935)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java 2006-12-06
13:04:31 UTC (rev 10936)
@@ -12,7 +12,6 @@
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.dialect.MySQLDialect;
-import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.ast.HqlSqlWalker;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.persister.entity.EntityPersister;
@@ -520,15 +519,17 @@
count = s.createQuery( updateQryString ).executeUpdate();
assertEquals( 1, count );
// many-to-many test
- updateQryString = "update SimpleEntityWithAssociation e " +
- "set e.name = 'updated' " +
- "where exists (" +
- " select a.id " +
- " from e.manyToManyAssociatedEntities a " +
- " where a.name = 'many-to-many-association'
" +
- ")";
- count = s.createQuery( updateQryString ).executeUpdate();
- assertEquals( 1, count );
+ if ( supportsSubqueryOnMutatingTable() ) {
+ updateQryString = "update SimpleEntityWithAssociation e " +
+ "set e.name = 'updated' " +
+ "where exists (" +
+ " select a.id " +
+ " from e.manyToManyAssociatedEntities a " +
+ " where a.name = 'many-to-many-association' " +
+ ")";
+ count = s.createQuery( updateQryString ).executeUpdate();
+ assertEquals( 1, count );
+ }
s.delete( entity.getManyToManyAssociatedEntities().iterator().next() );
s.delete( entity );
t.commit();
@@ -915,8 +916,10 @@
assertEquals( "incorrect delete count", 1, count );
// HHH-873...
- count = s.createQuery( "delete from User u where u not in (select u from User
u)" ).executeUpdate();
- assertEquals( 0, count );
+ if ( supportsSubqueryOnMutatingTable() ) {
+ count = s.createQuery( "delete from User u where u not in (select u from User
u)" ).executeUpdate();
+ assertEquals( 0, count );
+ }
count = s.createQuery( "delete Animal a" ).executeUpdate();
assertEquals( "Incorrect delete count", 4, count );