001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jdbc.support; 018 019import org.springframework.util.StringUtils; 020 021/** 022 * JavaBean for holding JDBC error codes for a particular database. 023 * Instances of this class are normally loaded through a bean factory. 024 * 025 * <p>Used by Spring's {@link SQLErrorCodeSQLExceptionTranslator}. 026 * The file "sql-error-codes.xml" in this package contains default 027 * {@code SQLErrorCodes} instances for various databases. 028 * 029 * @author Thomas Risberg 030 * @author Juergen Hoeller 031 * @see SQLErrorCodesFactory 032 * @see SQLErrorCodeSQLExceptionTranslator 033 */ 034public class SQLErrorCodes { 035 036 private String[] databaseProductNames; 037 038 private boolean useSqlStateForTranslation = false; 039 040 private String[] badSqlGrammarCodes = new String[0]; 041 042 private String[] invalidResultSetAccessCodes = new String[0]; 043 044 private String[] duplicateKeyCodes = new String[0]; 045 046 private String[] dataIntegrityViolationCodes = new String[0]; 047 048 private String[] permissionDeniedCodes = new String[0]; 049 050 private String[] dataAccessResourceFailureCodes = new String[0]; 051 052 private String[] transientDataAccessResourceCodes = new String[0]; 053 054 private String[] cannotAcquireLockCodes = new String[0]; 055 056 private String[] deadlockLoserCodes = new String[0]; 057 058 private String[] cannotSerializeTransactionCodes = new String[0]; 059 060 private CustomSQLErrorCodesTranslation[] customTranslations; 061 062 private SQLExceptionTranslator customSqlExceptionTranslator; 063 064 065 /** 066 * Set this property if the database name contains spaces, 067 * in which case we can not use the bean name for lookup. 068 */ 069 public void setDatabaseProductName(String databaseProductName) { 070 this.databaseProductNames = new String[] {databaseProductName}; 071 } 072 073 public String getDatabaseProductName() { 074 return (this.databaseProductNames != null && this.databaseProductNames.length > 0 ? 075 this.databaseProductNames[0] : null); 076 } 077 078 /** 079 * Set this property to specify multiple database names that contains spaces, 080 * in which case we can not use bean names for lookup. 081 */ 082 public void setDatabaseProductNames(String... databaseProductNames) { 083 this.databaseProductNames = databaseProductNames; 084 } 085 086 public String[] getDatabaseProductNames() { 087 return this.databaseProductNames; 088 } 089 090 /** 091 * Set this property to true for databases that do not provide an error code 092 * but that do provide SQL State (this includes PostgreSQL). 093 */ 094 public void setUseSqlStateForTranslation(boolean useStateCodeForTranslation) { 095 this.useSqlStateForTranslation = useStateCodeForTranslation; 096 } 097 098 public boolean isUseSqlStateForTranslation() { 099 return this.useSqlStateForTranslation; 100 } 101 102 public void setBadSqlGrammarCodes(String... badSqlGrammarCodes) { 103 this.badSqlGrammarCodes = StringUtils.sortStringArray(badSqlGrammarCodes); 104 } 105 106 public String[] getBadSqlGrammarCodes() { 107 return this.badSqlGrammarCodes; 108 } 109 110 public void setInvalidResultSetAccessCodes(String... invalidResultSetAccessCodes) { 111 this.invalidResultSetAccessCodes = StringUtils.sortStringArray(invalidResultSetAccessCodes); 112 } 113 114 public String[] getInvalidResultSetAccessCodes() { 115 return this.invalidResultSetAccessCodes; 116 } 117 118 public String[] getDuplicateKeyCodes() { 119 return duplicateKeyCodes; 120 } 121 122 public void setDuplicateKeyCodes(String... duplicateKeyCodes) { 123 this.duplicateKeyCodes = duplicateKeyCodes; 124 } 125 126 public void setDataIntegrityViolationCodes(String... dataIntegrityViolationCodes) { 127 this.dataIntegrityViolationCodes = StringUtils.sortStringArray(dataIntegrityViolationCodes); 128 } 129 130 public String[] getDataIntegrityViolationCodes() { 131 return this.dataIntegrityViolationCodes; 132 } 133 134 public void setPermissionDeniedCodes(String... permissionDeniedCodes) { 135 this.permissionDeniedCodes = StringUtils.sortStringArray(permissionDeniedCodes); 136 } 137 138 public String[] getPermissionDeniedCodes() { 139 return this.permissionDeniedCodes; 140 } 141 142 public void setDataAccessResourceFailureCodes(String... dataAccessResourceFailureCodes) { 143 this.dataAccessResourceFailureCodes = StringUtils.sortStringArray(dataAccessResourceFailureCodes); 144 } 145 146 public String[] getDataAccessResourceFailureCodes() { 147 return this.dataAccessResourceFailureCodes; 148 } 149 150 public void setTransientDataAccessResourceCodes(String... transientDataAccessResourceCodes) { 151 this.transientDataAccessResourceCodes = StringUtils.sortStringArray(transientDataAccessResourceCodes); 152 } 153 154 public String[] getTransientDataAccessResourceCodes() { 155 return this.transientDataAccessResourceCodes; 156 } 157 158 public void setCannotAcquireLockCodes(String... cannotAcquireLockCodes) { 159 this.cannotAcquireLockCodes = StringUtils.sortStringArray(cannotAcquireLockCodes); 160 } 161 162 public String[] getCannotAcquireLockCodes() { 163 return this.cannotAcquireLockCodes; 164 } 165 166 public void setDeadlockLoserCodes(String... deadlockLoserCodes) { 167 this.deadlockLoserCodes = StringUtils.sortStringArray(deadlockLoserCodes); 168 } 169 170 public String[] getDeadlockLoserCodes() { 171 return this.deadlockLoserCodes; 172 } 173 174 public void setCannotSerializeTransactionCodes(String... cannotSerializeTransactionCodes) { 175 this.cannotSerializeTransactionCodes = StringUtils.sortStringArray(cannotSerializeTransactionCodes); 176 } 177 178 public String[] getCannotSerializeTransactionCodes() { 179 return this.cannotSerializeTransactionCodes; 180 } 181 182 public void setCustomTranslations(CustomSQLErrorCodesTranslation... customTranslations) { 183 this.customTranslations = customTranslations; 184 } 185 186 public CustomSQLErrorCodesTranslation[] getCustomTranslations() { 187 return this.customTranslations; 188 } 189 190 public void setCustomSqlExceptionTranslatorClass(Class<? extends SQLExceptionTranslator> customTranslatorClass) { 191 if (customTranslatorClass != null) { 192 try { 193 this.customSqlExceptionTranslator = customTranslatorClass.newInstance(); 194 } 195 catch (Throwable ex) { 196 throw new IllegalStateException("Unable to instantiate custom translator", ex); 197 } 198 } 199 else { 200 this.customSqlExceptionTranslator = null; 201 } 202 } 203 204 public void setCustomSqlExceptionTranslator(SQLExceptionTranslator customSqlExceptionTranslator) { 205 this.customSqlExceptionTranslator = customSqlExceptionTranslator; 206 } 207 208 public SQLExceptionTranslator getCustomSqlExceptionTranslator() { 209 return this.customSqlExceptionTranslator; 210 } 211 212}