clean up SQLExceptionConverter and friends removing obsolete stuff

This commit is contained in:
Gavin King 2022-01-25 21:26:34 +01:00
parent e51c210d78
commit 6b51952137
11 changed files with 88 additions and 119 deletions

View File

@ -9,8 +9,9 @@ package org.hibernate.engine.jdbc.dialect.spi;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.exception.internal.SQLStateConverter; import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor; import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
@ -34,7 +35,9 @@ public class BasicSQLExceptionConverter {
*/ */
public static final String MSG = LOG.unableToQueryDatabaseMetadata(); public static final String MSG = LOG.unableToQueryDatabaseMetadata();
private static final SQLStateConverter CONVERTER = new SQLStateConverter( sqle ->"???" ); private static final SQLExceptionConverter CONVERTER = new StandardSQLExceptionConverter(
new SQLStateConversionDelegate(() -> sqle ->"???" )
);
/** /**
* Perform a conversion. * Perform a conversion.

View File

@ -14,9 +14,9 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.exception.internal.SQLStateConverter; import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.exception.spi.SQLExceptionConverter; import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
@ -38,7 +38,9 @@ public class SqlExceptionHelper {
private static final String DEFAULT_WARNING_MSG = "SQL Warning"; private static final String DEFAULT_WARNING_MSG = "SQL Warning";
private final boolean logWarnings; private final boolean logWarnings;
private static final SQLExceptionConverter DEFAULT_CONVERTER = new SQLStateConverter( e -> null ); private static final SQLExceptionConverter DEFAULT_CONVERTER = new StandardSQLExceptionConverter(
new SQLStateConversionDelegate( () -> e -> null )
);
private SQLExceptionConverter sqlExceptionConverter; private SQLExceptionConverter sqlExceptionConverter;
@ -76,7 +78,7 @@ public class SqlExceptionHelper {
* @param sqlExceptionConverter The converter to use. * @param sqlExceptionConverter The converter to use.
*/ */
public void setSqlExceptionConverter(SQLExceptionConverter sqlExceptionConverter) { public void setSqlExceptionConverter(SQLExceptionConverter sqlExceptionConverter) {
this.sqlExceptionConverter = ( sqlExceptionConverter == null ? DEFAULT_CONVERTER : sqlExceptionConverter ); this.sqlExceptionConverter = sqlExceptionConverter == null ? DEFAULT_CONVERTER : sqlExceptionConverter;
} }
// SQLException ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SQLException ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -29,8 +29,9 @@ import org.hibernate.exception.spi.AbstractSQLExceptionConversionDelegate;
import org.hibernate.exception.spi.ConversionContext; import org.hibernate.exception.spi.ConversionContext;
/** /**
* {@link org.hibernate.exception.spi.SQLExceptionConverter} implementation that does conversion based on the * A {@link org.hibernate.exception.spi.SQLExceptionConverter} implementation
* JDBC 4 defined {@link SQLException} sub-type hierarchy. * that does conversion based on the {@link SQLException} subtype hierarchy
* defined by JDBC 4.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -41,17 +42,17 @@ public class SQLExceptionTypeDelegate extends AbstractSQLExceptionConversionDele
@Override @Override
public JDBCException convert(SQLException sqlException, String message, String sql) { public JDBCException convert(SQLException sqlException, String message, String sql) {
if ( SQLClientInfoException.class.isInstance( sqlException ) if ( sqlException instanceof SQLClientInfoException
|| SQLInvalidAuthorizationSpecException.class.isInstance( sqlException ) || sqlException instanceof SQLInvalidAuthorizationSpecException
|| SQLNonTransientConnectionException.class.isInstance( sqlException ) || sqlException instanceof SQLNonTransientConnectionException
|| SQLTransientConnectionException.class.isInstance( sqlException ) ) { || sqlException instanceof SQLTransientConnectionException ) {
return new JDBCConnectionException( message, sqlException, sql ); return new JDBCConnectionException( message, sqlException, sql );
} }
else if ( DataTruncation.class.isInstance( sqlException ) || else if ( sqlException instanceof DataTruncation ||
SQLDataException.class.isInstance( sqlException ) ) { sqlException instanceof SQLDataException ) {
throw new DataException( message, sqlException, sql ); throw new DataException( message, sqlException, sql );
} }
else if ( SQLIntegrityConstraintViolationException.class.isInstance( sqlException ) ) { else if ( sqlException instanceof SQLIntegrityConstraintViolationException ) {
return new ConstraintViolationException( return new ConstraintViolationException(
message, message,
sqlException, sqlException,
@ -59,13 +60,13 @@ public class SQLExceptionTypeDelegate extends AbstractSQLExceptionConversionDele
getConversionContext().getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) getConversionContext().getViolatedConstraintNameExtractor().extractConstraintName( sqlException )
); );
} }
else if ( SQLSyntaxErrorException.class.isInstance( sqlException ) ) { else if ( sqlException instanceof SQLSyntaxErrorException ) {
return new SQLGrammarException( message, sqlException, sql ); return new SQLGrammarException( message, sqlException, sql );
} }
else if ( SQLTimeoutException.class.isInstance( sqlException ) ) { else if ( sqlException instanceof SQLTimeoutException ) {
return new QueryTimeoutException( message, sqlException, sql ); return new QueryTimeoutException( message, sqlException, sql );
} }
else if ( SQLTransactionRollbackException.class.isInstance( sqlException ) ) { else if ( sqlException instanceof SQLTransactionRollbackException ) {
// Not 100% sure this is completely accurate. The JavaDocs for SQLTransactionRollbackException state that // Not 100% sure this is completely accurate. The JavaDocs for SQLTransactionRollbackException state that
// it indicates sql states starting with '40' and that those usually indicate that: // it indicates sql states starting with '40' and that those usually indicate that:
// <quote> // <quote>

View File

@ -22,14 +22,14 @@ import org.hibernate.exception.spi.ConversionContext;
import org.hibernate.internal.util.JdbcExceptionHelper; import org.hibernate.internal.util.JdbcExceptionHelper;
/** /**
* A SQLExceptionConverter implementation which performs conversion based on the underlying SQLState. * A {@link org.hibernate.exception.spi.SQLExceptionConverter} implementation which performs conversion based
* Interpretation of a SQL error based on SQLState is not nearly as accurate as using the ErrorCode (which is, * on the underlying SQLState. Interpretation of a SQL error based on SQLState is not nearly as accurate as
* however, vendor-specific). * using the ErrorCode (which is, however, vendor-specific).
* * <p>
* SQLState codes are defined by both ANSI SQL specs and X/Open. Some of the "classes" are shared, others are * SQLState codes are defined by both ANSI SQL specs and X/Open. Some "classes" are shared, others are
* specific to one or another, yet others are custom vendor classes. Unfortunately I have not been able to * specific to one or another, yet others are custom vendor classes. Unfortunately I have not been able to
* find a "blessed" list of X/Open codes. These codes are cobbled together between ANSI SQL spec and error * find a "blessed" list of X/Open codes. These codes are cobbled together between ANSI SQL spec and error
* code tables from few vendors documentation. * code tables from few vendor's documentation.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -48,7 +48,7 @@ public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDe
); );
} }
private static final Set DATA_CATEGORIES = buildDataCategories(); private static final Set<String> DATA_CATEGORIES = buildDataCategories();
private static Set<String> buildDataCategories() { private static Set<String> buildDataCategories() {
return Set.of( return Set.of(
"21", // "cardinality violation" "21", // "cardinality violation"
@ -56,7 +56,7 @@ public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDe
); );
} }
private static final Set INTEGRITY_VIOLATION_CATEGORIES = buildContraintCategories(); private static final Set<String> INTEGRITY_VIOLATION_CATEGORIES = buildContraintCategories();
private static Set<String> buildContraintCategories() { private static Set<String> buildContraintCategories() {
return Set.of( return Set.of(
"23", // "integrity constraint violation" "23", // "integrity constraint violation"
@ -65,7 +65,7 @@ public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDe
); );
} }
private static final Set CONNECTION_CATEGORIES = buildConnectionCategories(); private static final Set<String> CONNECTION_CATEGORIES = buildConnectionCategories();
private static Set<String> buildConnectionCategories() { private static Set<String> buildConnectionCategories() {
return Set.of( return Set.of(
"08" // "connection exception" "08" // "connection exception"

View File

@ -1,31 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.exception.internal;
import org.hibernate.exception.spi.ConversionContext;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
/**
* @deprecated Use {@link StandardSQLExceptionConverter} with {@link SQLStateConversionDelegate}
* instead
*
* @author Steve Ebersole
*/
@Deprecated
public class SQLStateConverter extends StandardSQLExceptionConverter implements SQLExceptionConverter {
public SQLStateConverter(final ViolatedConstraintNameExtractor extractor) {
super();
final ConversionContext conversionContext = new ConversionContext() {
@Override
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
return extractor;
}
};
addDelegate( new SQLStateConversionDelegate( conversionContext ) );
}
}

View File

@ -6,24 +6,44 @@
*/ */
package org.hibernate.exception.internal; package org.hibernate.exception.internal;
import java.sql.SQLException;
import java.util.ArrayList;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.exception.GenericJDBCException; import org.hibernate.exception.GenericJDBCException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate; import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.SQLExceptionConverter; import org.hibernate.exception.spi.SQLExceptionConverter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* A {@link SQLExceptionConverter} that delegates to a chain of
* {@link SQLExceptionConversionDelegate}.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class StandardSQLExceptionConverter implements SQLExceptionConverter { public class StandardSQLExceptionConverter implements SQLExceptionConverter {
private final ArrayList<SQLExceptionConversionDelegate> delegates = new ArrayList<>(); private final List<SQLExceptionConversionDelegate> delegates;
public StandardSQLExceptionConverter() { public StandardSQLExceptionConverter(SQLExceptionConversionDelegate... delegates) {
this.delegates = Arrays.asList(delegates);
} }
/**
* @deprecated use {@link #StandardSQLExceptionConverter(SQLExceptionConversionDelegate...)}
*/
@Deprecated(since = "6.0")
public StandardSQLExceptionConverter() {
delegates = new ArrayList<>();
}
/**
* Add a delegate.
*
* @deprecated use {@link #StandardSQLExceptionConverter(SQLExceptionConversionDelegate...)}
*/
@Deprecated(since = "6.0")
public void addDelegate(SQLExceptionConversionDelegate delegate) { public void addDelegate(SQLExceptionConversionDelegate delegate) {
if ( delegate != null ) { if ( delegate != null ) {
this.delegates.add( delegate ); this.delegates.add( delegate );

View File

@ -1,28 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.exception.spi;
import java.util.Properties;
import org.hibernate.HibernateException;
/**
* This interface defines the contract for {@link SQLExceptionConverter}
* implementations that want to be configured prior to usage given the
* currently defined Hibernate properties.
*
* @author Steve Ebersole
*/
public interface Configurable {
/**
* Configure the component, using the given settings and properties.
*
* @param properties All defined startup properties.
* @throws HibernateException Indicates a configuration exception.
*/
void configure(Properties properties) throws HibernateException;
}

View File

@ -11,21 +11,25 @@ import java.sql.SQLException;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
/** /**
* Allow a {@link SQLExceptionConverter} to work by chaining together multiple such delegates. The main * Allow a {@link SQLExceptionConverter} to work by chaining together
* difference between a delegate and a full-fledged converter is that a delegate may return {@code null}. * multiple delegates. The main difference between a delegate and a
* full-fledged converter is that a delegate may return {@code null}.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@FunctionalInterface @FunctionalInterface
public interface SQLExceptionConversionDelegate { public interface SQLExceptionConversionDelegate {
/** /**
* Convert the given SQLException into the Hibernate {@link JDBCException} hierarchy. * Convert the given {@link SQLException} to a subtype of
* {@link JDBCException}, if possible.
* *
* @param sqlException The SQLException to be converted. * @param sqlException The {@code SQLException} to be converted
* @param message An (optional) error message. * @param message An optional error message
* @param sql The {@literal SQL} statement, if one, being performed when the exception occurred. * @param sql The SQL statement that resulted in the exception
* *
* @return The resulting JDBCException, can be {@code null} * @return The resulting {@code JDBCException}, or {@code null}
* if this delegate does not know how to interpret the
* given {@link SQLException}.
*/ */
JDBCException convert(SQLException sqlException, String message, String sql); JDBCException convert(SQLException sqlException, String message, String sql);

View File

@ -12,24 +12,21 @@ import java.sql.SQLException;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
/** /**
* Defines a contract for implementations that know how to convert a * An object that interprets JDBC {@link SQLException}s and converts
* {@link SQLException} to Hibernate's {@link JDBCException} hierarchy. * them to subtypes of Hibernate {@link JDBCException}s.
* <p/>
* Implementations <b>must</b> have a constructor which takes a
* {@link ViolatedConstraintNameExtractor} parameter.
* <p/>
* Implementations may implement {@link Configurable} if they need to
* perform configuration steps prior to first use.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface SQLExceptionConverter extends Serializable { public interface SQLExceptionConverter extends Serializable {
/** /**
* Convert the given SQLException into the Hibernate {@link JDBCException} hierarchy. * Convert the given {@link SQLException} to a subtype of
* {@link JDBCException}.
* *
* @param sqlException The SQLException to be converted. * @param sqlException The {@code SQLException} to be converted
* @param message An optional error message. * @param message An optional error message
* @return The resulting JDBCException. * @param sql The SQL statement that resulted in the exception
*
* @return The resulting {@code JDBCException}.
* *
* @see org.hibernate.exception.ConstraintViolationException * @see org.hibernate.exception.ConstraintViolationException
* @see org.hibernate.exception.JDBCConnectionException * @see org.hibernate.exception.JDBCConnectionException

View File

@ -10,15 +10,15 @@ import java.sql.SQLException;
import java.util.function.Function; import java.util.function.Function;
/** /**
* Knows how to extract a violated constraint name from an error message based on the * Extracts a violated database constraint name from an error message
* fact that the constraint name is templated within the message. * by matching the error message against a template.
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Brett Meyer * @author Brett Meyer
*/ */
public class TemplatedViolatedConstraintNameExtractor implements ViolatedConstraintNameExtractor { public class TemplatedViolatedConstraintNameExtractor implements ViolatedConstraintNameExtractor {
private Function<SQLException,String> extractConstraintName; private final Function<SQLException,String> extractConstraintName;
public TemplatedViolatedConstraintNameExtractor(Function<SQLException,String> extractConstraintName) { public TemplatedViolatedConstraintNameExtractor(Function<SQLException,String> extractConstraintName) {
this.extractConstraintName = extractConstraintName; this.extractConstraintName = extractConstraintName;
@ -49,7 +49,8 @@ public class TemplatedViolatedConstraintNameExtractor implements ViolatedConstra
} }
/** /**
* Extracts the constraint name based on a template (i.e., <i>templateStart</i><b>constraintName</b><i>templateEnd</i>). * Extracts the constraint name based on a template of form
* <i>templateStart</i><b>constraintName</b><i>templateEnd</i>.
* *
* @param templateStart The pattern denoting the start of the constraint name within the message. * @param templateStart The pattern denoting the start of the constraint name within the message.
* @param templateEnd The pattern denoting the end of the constraint name within the message. * @param templateEnd The pattern denoting the end of the constraint name within the message.

View File

@ -9,16 +9,16 @@ package org.hibernate.exception.spi;
import java.sql.SQLException; import java.sql.SQLException;
/** /**
* Defines a contract for implementations that can extract the name of a violated * An object that can extract the name of a violated database constraint
* constraint from a {@link SQLException} that is the result of that constraint * from a {@link SQLException} that results from the constraint violation.
* violation.
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@FunctionalInterface @FunctionalInterface
public interface ViolatedConstraintNameExtractor { public interface ViolatedConstraintNameExtractor {
/** /**
* Extract the name of the violated constraint from the given SQLException. * Extract the name of the violated constraint from the given
* {@link SQLException}.
* *
* @param sqle The exception that was the result of the constraint violation. * @param sqle The exception that was the result of the constraint violation.
* @return The extracted constraint name. * @return The extracted constraint name.