⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlerrorcodesqlexceptiontranslator.java

📁 spring的源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			}
			else {
				errorCode = Integer.toString(sqlEx.getErrorCode());
			}

			if (errorCode != null) {

				// Look for defined custom translations first.
				CustomSQLErrorCodesTranslation[] customTranslations = this.sqlErrorCodes.getCustomTranslations();
				if (customTranslations != null) {
					for (int i = 0; i < customTranslations.length; i++) {
						CustomSQLErrorCodesTranslation customTranslation = customTranslations[i];
						if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0) {
							if (customTranslation.getExceptionClass() != null) {
								DataAccessException customException = createCustomException(
										task, sql, sqlEx, customTranslation.getExceptionClass());
								if (customException != null) {
									logTranslation(task, sql, sqlEx, true);
									return customException;
								}
							}
						}
					}
				}

				// Next, look for grouped error codes.
				if (Arrays.binarySearch(this.sqlErrorCodes.getBadSqlGrammarCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new BadSqlGrammarException(task, sql, sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new InvalidResultSetAccessException(task, sql, sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getDataAccessResourceFailureCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getDataIntegrityViolationCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotAcquireLockCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getDeadlockLoserCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new DeadlockLoserDataAccessException(buildMessage(task, sql, sqlEx), sqlEx);
				}
				else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotSerializeTransactionCodes(), errorCode) >= 0) {
					logTranslation(task, sql, sqlEx, false);
					return new CannotSerializeTransactionException(buildMessage(task, sql, sqlEx), sqlEx);
				}
			}
		}

		// We couldn't identify it more precisely - let's hand it over to the SQLState fallback translator.
		if (logger.isDebugEnabled()) {
			logger.debug("Unable to translate SQLException with errorCode '" + sqlEx.getErrorCode() +
					"', will now try the fallback translator");
		}
		return this.fallbackTranslator.translate(task, sql, sqlEx);
	}

	/**
	 * Build a message String for the given SQLException.
	 * Called when creating an instance of a generic DataAccessException class.
	 * @param task readable text describing the task being attempted
	 * @param sql SQL query or update that caused the problem. May be <code>null</code>.
	 * @param sqlEx the offending SQLException
	 * @return the message String to use
	 */
	protected String buildMessage(String task, String sql, SQLException sqlEx) {
		return task + "; SQL [" + sql + "]; " + sqlEx.getMessage();
	}

	/**
	 * Subclasses can override this method to attempt a custom mapping from SQLException
	 * to DataAccessException.
	 * @param task readable text describing the task being attempted
	 * @param sql SQL query or update that caused the problem. May be <code>null</code>.
	 * @param sqlEx the offending SQLException
	 * @return null if no custom translation was possible, otherwise a DataAccessException
	 * resulting from custom translation. This exception should include the sqlEx parameter
	 * as a nested root cause. This implementation always returns null, meaning that
	 * the translator always falls back to the default error codes.
	 */
	protected DataAccessException customTranslate(String task, String sql, SQLException sqlEx) {
		return null;
	}

	/**
	 * Create a custom DataAccessException, based on a given exception
	 * class from a CustomSQLErrorCodesTranslation definition.
	 * @param task readable text describing the task being attempted
	 * @param sql SQL query or update that caused the problem. May be <code>null</code>.
	 * @param sqlEx the offending SQLException
	 * @param exceptionClass the exception class to use, as defined in the
	 * CustomSQLErrorCodesTranslation definition
	 * @return null if the custom exception could not be created, otherwise
	 * the resulting DataAccessException. This exception should include the
	 * sqlEx parameter as a nested root cause.
	 * @see CustomSQLErrorCodesTranslation#setExceptionClass
	 */
	protected DataAccessException createCustomException(
			String task, String sql, SQLException sqlEx, Class exceptionClass) {

		// find appropriate constructor
		try {
			int constructorType = 0;
			Constructor[] constructors = exceptionClass.getConstructors();
			for (int i = 0; i < constructors.length; i++) {
				Class[] parameterTypes = constructors[i].getParameterTypes();
				if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
					if (constructorType < MESSAGE_ONLY_CONSTRUCTOR)
						constructorType = MESSAGE_ONLY_CONSTRUCTOR;
				}
				if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) &&
						parameterTypes[1].equals(Throwable.class)) {
					if (constructorType < MESSAGE_THROWABLE_CONSTRUCTOR)
						constructorType = MESSAGE_THROWABLE_CONSTRUCTOR;
				}
				if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) &&
						parameterTypes[1].equals(SQLException.class)) {
					if (constructorType < MESSAGE_SQLEX_CONSTRUCTOR)
						constructorType = MESSAGE_SQLEX_CONSTRUCTOR;
				}
				if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) &&
						parameterTypes[1].equals(String.class) && parameterTypes[2].equals(Throwable.class)) {
					if (constructorType < MESSAGE_SQL_THROWABLE_CONSTRUCTOR)
						constructorType = MESSAGE_SQL_THROWABLE_CONSTRUCTOR;
				}
				if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) &&
						parameterTypes[1].equals(String.class) && parameterTypes[2].equals(SQLException.class)) {
					if (constructorType < MESSAGE_SQL_SQLEX_CONSTRUCTOR)
						constructorType = MESSAGE_SQL_SQLEX_CONSTRUCTOR;
				}
			}

			// invoke constructor
			Constructor exceptionConstructor = null;
			switch (constructorType) {
				case MESSAGE_SQL_SQLEX_CONSTRUCTOR:
					Class[] messageAndSqlAndSqlExArgsClass = new Class[] {String.class, String.class, SQLException.class};
					Object[] messageAndSqlAndSqlExArgs = new Object[] {task, sql, sqlEx};
					exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndSqlExArgsClass);
					return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndSqlExArgs);
				case MESSAGE_SQL_THROWABLE_CONSTRUCTOR:
					Class[] messageAndSqlAndThrowableArgsClass = new Class[] {String.class, String.class, Throwable.class};
					Object[] messageAndSqlAndThrowableArgs = new Object[] {task, sql, sqlEx};
					exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndThrowableArgsClass);
					return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndThrowableArgs);
				case MESSAGE_SQLEX_CONSTRUCTOR:
					Class[] messageAndSqlExArgsClass = new Class[] {String.class, SQLException.class};
					Object[] messageAndSqlExArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx};
					exceptionConstructor = exceptionClass.getConstructor(messageAndSqlExArgsClass);
					return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlExArgs);
				case MESSAGE_THROWABLE_CONSTRUCTOR:
					Class[] messageAndThrowableArgsClass = new Class[] {String.class, Throwable.class};
					Object[] messageAndThrowableArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx};
					exceptionConstructor = exceptionClass.getConstructor(messageAndThrowableArgsClass);
					return (DataAccessException)exceptionConstructor.newInstance(messageAndThrowableArgs);
				case MESSAGE_ONLY_CONSTRUCTOR:
					Class[] messageOnlyArgsClass = new Class[] {String.class};
					Object[] messageOnlyArgs = new Object[] {task + ": " + sqlEx.getMessage()};
					exceptionConstructor = exceptionClass.getConstructor(messageOnlyArgsClass);
					return (DataAccessException) exceptionConstructor.newInstance(messageOnlyArgs);
				default:
					logger.warn("Unable to find appropriate constructor of custom exception class [" +
							exceptionClass.getName() + "]");
					return null;
				}
		}
		catch (Exception ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Unable to instantiate custom exception class [" + exceptionClass.getName() + "]", ex);
			}
			return null;
		}
	}

	private void logTranslation(String task, String sql, SQLException sqlEx, boolean custom) {
		if (logger.isDebugEnabled()) {
			String intro = custom ? "Custom translation of" : "Translating";
			logger.debug(intro + " SQLException with SQLState '" + sqlEx.getSQLState() +
					"' and errorCode '" + sqlEx.getErrorCode() + "' and message [" + sqlEx.getMessage() +
					"]; SQL was [" + sql + "] for task [" + task + "]");
		}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -