[hibernate-commits] Hibernate SVN: r19931 - in core/trunk/core/src/main/java/org/hibernate: util and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Jul 11 18:16:38 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-07-11 18:16:38 -0400 (Sun, 11 Jul 2010)
New Revision: 19931

Modified:
   core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
   core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java
Log:
HHH-5373 - Better account for SQLWarnings in temp table creation 


Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2010-07-10 13:48:34 UTC (rev 19930)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2010-07-11 22:16:38 UTC (rev 19931)
@@ -1,10 +1,10 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
  * indicated by the @author tags or express copyright attribution
  * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
  *
  * This copyrighted material is made available to anyone wishing to use, modify,
  * copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,12 +20,12 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.hql.ast.exec;
 
 import java.sql.PreparedStatement;
 import java.sql.Connection;
+import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.List;
 import java.util.Collections;
@@ -43,12 +43,14 @@
 import org.hibernate.sql.InsertSelect;
 import org.hibernate.sql.Select;
 import org.hibernate.sql.SelectFragment;
+import org.hibernate.util.JDBCExceptionReporter;
 import org.hibernate.util.StringHelper;
 
 import antlr.RecognitionException;
 import antlr.collections.AST;
 
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of AbstractStatementExecutor.
@@ -56,6 +58,7 @@
  * @author Steve Ebersole
  */
 public abstract class AbstractStatementExecutor implements StatementExecutor {
+	private static final Logger LOG = LoggerFactory.getLogger( AbstractStatementExecutor.class );
 
 	private final Logger log;
 	private final HqlSqlWalker walker;
@@ -141,24 +144,24 @@
 		// simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
 		IsolatedWork work = new IsolatedWork() {
 			public void doWork(Connection connection) throws HibernateException {
-				Statement stmnt = null;
 				try {
-					stmnt = connection.createStatement();
-					stmnt.executeUpdate( persister.getTemporaryIdTableDDL() );
-				}
-				catch( Throwable t ) {
-					log.debug( "unable to create temporary id table [" + t.getMessage() + "]" );
-				}
-				finally {
-					if ( stmnt != null ) {
+					Statement statement = connection.createStatement();
+					try {
+						statement.executeUpdate( persister.getTemporaryIdTableDDL() );
+						JDBCExceptionReporter.handleAndClearWarnings( statement, CREATION_WARNING_HANDLER );
+					}
+					finally {
 						try {
-							stmnt.close();
+							statement.close();
 						}
 						catch( Throwable ignore ) {
 							// ignore
 						}
 					}
 				}
+				catch( Exception e ) {
+					log.debug( "unable to create temporary id table [" + e.getMessage() + "]" );
+				}
 			}
 		};
 		if ( shouldIsolateTemporaryTableDDL() ) {
@@ -175,30 +178,46 @@
 		}
 	}
 
+	private static JDBCExceptionReporter.WarningHandler CREATION_WARNING_HANDLER = new JDBCExceptionReporter.WarningHandlerLoggingSupport() {
+		public boolean doProcess() {
+			return LOG.isDebugEnabled();
+		}
+
+		public void prepare(SQLWarning warning) {
+			LOG.debug( "Warnings creating temp table", warning );
+		}
+
+		@Override
+		protected void logWarning(String description, String message) {
+			LOG.debug( description );
+			LOG.debug( message );
+		}
+	};
+
 	protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
 		if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
 			IsolatedWork work = new IsolatedWork() {
 				public void doWork(Connection connection) throws HibernateException {
-					Statement stmnt = null;
+					final String command = session.getFactory().getSettings().getDialect().getDropTemporaryTableString()
+							+ ' ' + persister.getTemporaryIdTableName();
 					try {
-						final String command = session.getFactory().getSettings().getDialect().getDropTemporaryTableString()
-								+ " " + persister.getTemporaryIdTableName();
-						stmnt = connection.createStatement();
-						stmnt.executeUpdate( command );
-					}
-					catch( Throwable t ) {
-						log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" );
-					}
-					finally {
-						if ( stmnt != null ) {
+						Statement statement = connection.createStatement();
+						try {
+							statement = connection.createStatement();
+							statement.executeUpdate( command );
+						}
+						finally {
 							try {
-								stmnt.close();
+								statement.close();
 							}
 							catch( Throwable ignore ) {
 								// ignore
 							}
 						}
 					}
+					catch( Exception e ) {
+						log.warn( "unable to drop temporary id table after use [" + e.getMessage() + "]" );
+					}
 				}
 			};
 
@@ -249,6 +268,7 @@
 		}
 	}
 
+	@SuppressWarnings({ "UnnecessaryUnboxing" })
 	protected boolean shouldIsolateTemporaryTableDDL() {
 		Boolean dialectVote = getFactory().getDialect().performTemporaryTableDDLInIsolation();
 		if ( dialectVote != null ) {

Modified: core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	2010-07-10 13:48:34 UTC (rev 19930)
+++ core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	2010-07-11 22:16:38 UTC (rev 19931)
@@ -1,10 +1,10 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
  * indicated by the @author tags or express copyright attribution
  * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
  *
  * This copyrighted material is made available to anyone wishing to use, modify,
  * copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,67 +20,200 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.util;
 
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLWarning;
+import java.sql.Statement;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class JDBCExceptionReporter {
-
 	public static final Logger log = LoggerFactory.getLogger(JDBCExceptionReporter.class);
 	public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
 	public static final String DEFAULT_WARNING_MSG = "SQL Warning";
 
 	private JDBCExceptionReporter() {}
-	
+
+	/**
+	 * Standard (legacy) behavior for logging warnings associated with a JDBC {@link Connection} and clearing them.
+	 * <p/>
+	 * Calls {@link #handleAndClearWarnings(Connection, WarningHandler)} using {@link #STANDARD_WARNING_HANDLER}
+	 *
+	 * @param connection The JDBC connection potentially containing warnings
+	 */
 	public static void logAndClearWarnings(Connection connection) {
-		if ( log.isWarnEnabled() ) {
-			try {
-				logWarnings( connection.getWarnings() );
-			}
-			catch (SQLException sqle) {
-				//workaround for WebLogic
-				log.debug("could not log warnings", sqle);
-			}
+		handleAndClearWarnings( connection, STANDARD_WARNING_HANDLER );
+	}
+
+	/**
+	 * General purpose handling of warnings associated with a JDBC {@link Connection}.
+	 *
+	 * @param connection The JDBC connection potentially containing warnings
+	 * @param handler The handler for each individual warning in the stack.
+	 *
+	 * @see #walkWarnings
+	 */
+	@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
+	public static void handleAndClearWarnings(Connection connection, WarningHandler handler) {
+		try {
+			walkWarnings( connection.getWarnings(), handler );
 		}
+		catch ( SQLException sqle ) {
+			//workaround for WebLogic
+			log.debug( "could not log warnings", sqle );
+		}
 		try {
 			//Sybase fail if we don't do that, sigh...
 			connection.clearWarnings();
 		}
-		catch (SQLException sqle) {
-			log.debug("could not clear warnings", sqle);
+		catch ( SQLException sqle ) {
+			log.debug( "could not clear warnings", sqle );
 		}
 	}
 
+	/**
+	 * General purpose handling of warnings associated with a JDBC {@link Statement}.
+	 *
+	 * @param statement The JDBC statement potentially containing warnings
+	 * @param handler The handler for each individual warning in the stack.
+	 *
+	 * @see #walkWarnings
+	 */
+	@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
+	public static void handleAndClearWarnings(Statement statement, WarningHandler handler) {
+		try {
+			walkWarnings( statement.getWarnings(), handler );
+		}
+		catch ( SQLException sqle ) {
+			//workaround for WebLogic
+			log.debug( "could not log warnings", sqle );
+		}
+		try {
+			//Sybase fail if we don't do that, sigh...
+			statement.clearWarnings();
+		}
+		catch ( SQLException sqle ) {
+			log.debug( "could not clear warnings", sqle );
+		}
+	}
+
+	/**
+	 * Log the given warning and all of its nested warnings, preceded with the {@link #DEFAULT_WARNING_MSG default message}
+	 *
+	 * @param warning The warning to log
+	 *
+	 * @deprecated Use {@link #walkWarnings} instead
+	 */
+	@Deprecated()
+	@SuppressWarnings({ "UnusedDeclaration" })
 	public static void logWarnings(SQLWarning warning) {
-		logWarnings(warning, null);
+		walkWarnings( warning, STANDARD_WARNING_HANDLER );
 	}
 
+	/**
+	 * Log the given warning and all of its nested warnings, preceded with the given message
+	 *
+	 * @param warning The warning to log
+	 * @param message The prologue message
+	 *
+	 * @deprecated Use {@link #walkWarnings} instead
+	 */
+	@Deprecated()
+	@SuppressWarnings({ "UnusedDeclaration" })
 	public static void logWarnings(SQLWarning warning, String message) {
-		if ( log.isWarnEnabled() ) {
-			if ( log.isDebugEnabled() && warning != null ) {
-				message = StringHelper.isNotEmpty(message) ? message : DEFAULT_WARNING_MSG;
-				log.debug( message, warning );
-			}
-			while (warning != null) {
-				StringBuffer buf = new StringBuffer(30)
-				        .append( "SQL Warning: ")
-						.append( warning.getErrorCode() )
-						.append( ", SQLState: ")
-						.append( warning.getSQLState() );
-				log.warn( buf.toString() );
-				log.warn( warning.getMessage() );
-				warning = warning.getNextWarning();
-			}
+		final WarningHandler handler = StringHelper.isNotEmpty(message)
+				? new StandardWarningHandler( message )
+				: STANDARD_WARNING_HANDLER;
+		walkWarnings( warning, handler );
+	}
+
+	/**
+	 * Contract for handling {@link SQLWarning warnings}
+	 */
+	public static interface WarningHandler {
+		/**
+		 * Should processing be done?  Allows short-circuiting if not.
+		 *
+		 * @return True to process warnings, false otherwise.
+		 */
+		public boolean doProcess();
+
+		/**
+		 * Prepare for processing of a {@link SQLWarning warning} stack.
+		 * <p/>
+		 * Note that the warning here is also the first passed to {@link #handleWarning}
+		 *
+		 * @param warning The first warning in the stack.
+		 */
+		public void prepare(SQLWarning warning);
+
+		/**
+		 * Handle an individual warning in the stack.
+		 *
+		 * @param warning The warning to handle.
+		 */
+		public void handleWarning(SQLWarning warning);
+	}
+
+	/**
+	 * Basic support for {@link WarningHandler} implementations which log
+	 */
+	public static abstract class WarningHandlerLoggingSupport implements WarningHandler {
+		public final void handleWarning(SQLWarning warning) {
+			StringBuffer buf = new StringBuffer(30)
+					.append( "SQL Warning Code: ").append( warning.getErrorCode() )
+					.append( ", SQLState: ").append( warning.getSQLState() );
+			logWarning( buf.toString(), warning.getMessage() );
 		}
+
+		/**
+		 * Delegate to log common details of a {@link SQLWarning warning}
+		 *
+		 * @param description A description of the warning
+		 * @param message The warning message
+		 */
+		protected abstract void logWarning(String description, String message);
 	}
 
+	public static class StandardWarningHandler extends WarningHandlerLoggingSupport {
+		private final String introMessage;
+
+		public StandardWarningHandler(String introMessage) {
+			this.introMessage = introMessage;
+		}
+
+		public boolean doProcess() {
+			return log.isWarnEnabled();
+		}
+
+		public void prepare(SQLWarning warning) {
+			log.debug( introMessage, warning );
+		}
+
+		@Override
+		protected void logWarning(String description, String message) {
+			log.warn( description );
+			log.warn( message );
+		}
+	}
+
+	public static StandardWarningHandler STANDARD_WARNING_HANDLER = new StandardWarningHandler( DEFAULT_WARNING_MSG );
+
+	public static void walkWarnings(SQLWarning warning, WarningHandler handler) {
+		if ( warning == null || handler.doProcess() ) {
+			return;
+		}
+		handler.prepare( warning );
+		while ( warning != null ) {
+			handler.handleWarning( warning );
+			warning = warning.getNextWarning();
+		}
+	}
+
 	public static void logExceptions(SQLException ex) {
 		logExceptions(ex, null);
 	}
@@ -103,20 +236,6 @@
 			}
 		}
 	}
-
-//	public static JDBCException newJDBCException(String string, SQLException root, String sql) {
-//		string = string + " [" + sql + ']';
-//		log.error(string, root);
-//		logExceptions(root);
-//		return new JDBCException(string, root, sql);
-//	}
-//
-//	public static JDBCException newJDBCException(String string, SQLException root) {
-//		log.error(string, root);
-//		logExceptions(root);
-//		return new JDBCException(string, root);
-//	}
-
 }
 
 



More information about the hibernate-commits mailing list