diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.java index 070ada3a306..8b4bd9c304f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.java @@ -22,7 +22,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.SpringProperties; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -41,13 +40,6 @@ import org.springframework.util.Assert; */ public abstract class JdbcAccessor implements InitializingBean { - /** - * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to - * ignore XML, i.e. to not initialize the XML-related infrastructure. - *
The default is "false". - */ - private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); - /** Logger available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); @@ -96,9 +88,12 @@ public abstract class JdbcAccessor implements InitializingBean { * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public void setDatabaseProductName(String dbName) { - if (!shouldIgnoreXml) { + if (SQLErrorCodeSQLExceptionTranslator.hasUserProvidedErrorCodesFile()) { this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dbName); } + else { + this.exceptionTranslator = new SQLExceptionSubclassTranslator(); + } } /** @@ -128,15 +123,11 @@ public abstract class JdbcAccessor implements InitializingBean { synchronized (this) { exceptionTranslator = this.exceptionTranslator; if (exceptionTranslator == null) { - DataSource dataSource = getDataSource(); - if (shouldIgnoreXml) { - exceptionTranslator = new SQLExceptionSubclassTranslator(); - } - else if (dataSource != null) { - exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource); + if (SQLErrorCodeSQLExceptionTranslator.hasUserProvidedErrorCodesFile()) { + exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(obtainDataSource()); } else { - exceptionTranslator = new SQLStateSQLExceptionTranslator(); + exceptionTranslator = new SQLExceptionSubclassTranslator(); } this.exceptionTranslator = exceptionTranslator; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcTransactionManager.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcTransactionManager.java index b1cab0b75d4..bda750f4722 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcTransactionManager.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.sql.SQLException; import javax.sql.DataSource; -import org.springframework.core.SpringProperties; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.lang.Nullable; @@ -53,14 +52,6 @@ import org.springframework.lang.Nullable; @SuppressWarnings("serial") public class JdbcTransactionManager extends DataSourceTransactionManager { - /** - * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to - * ignore XML, i.e. to not initialize the XML-related infrastructure. - *
The default is "false". - */ - private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore"); - - @Nullable private volatile SQLExceptionTranslator exceptionTranslator; @@ -97,9 +88,12 @@ public class JdbcTransactionManager extends DataSourceTransactionManager { * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public void setDatabaseProductName(String dbName) { - if (!shouldIgnoreXml) { + if (SQLErrorCodeSQLExceptionTranslator.hasUserProvidedErrorCodesFile()) { this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dbName); } + else { + this.exceptionTranslator = new SQLExceptionSubclassTranslator(); + } } /** @@ -128,11 +122,11 @@ public class JdbcTransactionManager extends DataSourceTransactionManager { synchronized (this) { exceptionTranslator = this.exceptionTranslator; if (exceptionTranslator == null) { - if (shouldIgnoreXml) { - exceptionTranslator = new SQLExceptionSubclassTranslator(); + if (SQLErrorCodeSQLExceptionTranslator.hasUserProvidedErrorCodesFile()) { + exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(obtainDataSource()); } else { - exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(obtainDataSource()); + exceptionTranslator = new SQLExceptionSubclassTranslator(); } this.exceptionTranslator = exceptionTranslator; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.java index e28af0160b3..609f16325ff 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.java @@ -23,6 +23,7 @@ import java.util.Arrays; import javax.sql.DataSource; +import org.springframework.core.io.ClassPathResource; import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.CannotSerializeTransactionException; import org.springframework.dao.DataAccessException; @@ -417,4 +418,14 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep } } + + /** + * Check whether there is a user-provided `sql-error-codes.xml` file + * in the root of the classpath. + */ + static boolean hasUserProvidedErrorCodesFile() { + return new ClassPathResource(SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH, + SQLErrorCodesFactory.class.getClassLoader()).exists(); + } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java index 2b78fa740f0..00869ece51b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.SpringProperties; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; @@ -66,6 +67,13 @@ public class SQLErrorCodesFactory { private static final Log logger = LogFactory.getLog(SQLErrorCodesFactory.class); + /** + * Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to + * ignore XML, i.e. to not initialize the XML-related infrastructure. + *
The default is "false".
+ */
+ private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
+
/**
* Keep track of a single instance so we can return it to classes that request it.
*/
@@ -101,6 +109,10 @@ public class SQLErrorCodesFactory {
* @see #loadResource(String)
*/
protected SQLErrorCodesFactory() {
+ if (shouldIgnoreXml) {
+ throw new UnsupportedOperationException("XML support disabled");
+ }
+
Map