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 org.hibernate.JDBCException;
import org.hibernate.exception.internal.SQLStateConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
@ -34,7 +35,9 @@ public class BasicSQLExceptionConverter {
*/
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.

View File

@ -14,9 +14,9 @@ import java.util.ArrayList;
import java.util.List;
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.ViolatedConstraintNameExtractor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
@ -38,7 +38,9 @@ public class SqlExceptionHelper {
private static final String DEFAULT_WARNING_MSG = "SQL Warning";
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;
@ -76,7 +78,7 @@ public class SqlExceptionHelper {
* @param sqlExceptionConverter The converter to use.
*/
public void setSqlExceptionConverter(SQLExceptionConverter sqlExceptionConverter) {
this.sqlExceptionConverter = ( sqlExceptionConverter == null ? DEFAULT_CONVERTER : sqlExceptionConverter );
this.sqlExceptionConverter = sqlExceptionConverter == null ? DEFAULT_CONVERTER : sqlExceptionConverter;
}
// SQLException ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

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

View File

@ -22,14 +22,14 @@ import org.hibernate.exception.spi.ConversionContext;
import org.hibernate.internal.util.JdbcExceptionHelper;
/**
* A SQLExceptionConverter implementation which performs conversion based on the underlying SQLState.
* Interpretation of a SQL error based on SQLState is not nearly as accurate as using the ErrorCode (which is,
* however, vendor-specific).
*
* SQLState codes are defined by both ANSI SQL specs and X/Open. Some of the "classes" are shared, others are
* A {@link org.hibernate.exception.spi.SQLExceptionConverter} implementation which performs conversion based
* on the underlying SQLState. Interpretation of a SQL error based on SQLState is not nearly as accurate as
* using the ErrorCode (which is, however, vendor-specific).
* <p>
* 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
* 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
*/
@ -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() {
return Set.of(
"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() {
return Set.of(
"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() {
return Set.of(
"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;
import java.sql.SQLException;
import java.util.ArrayList;
import org.hibernate.JDBCException;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
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
*/
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) {
if ( delegate != null ) {
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;
/**
* Allow a {@link SQLExceptionConverter} to work by chaining together multiple such delegates. The main
* difference between a delegate and a full-fledged converter is that a delegate may return {@code null}.
* Allow a {@link SQLExceptionConverter} to work by chaining together
* multiple delegates. The main difference between a delegate and a
* full-fledged converter is that a delegate may return {@code null}.
*
* @author Steve Ebersole
*/
@FunctionalInterface
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 message An (optional) error message.
* @param sql The {@literal SQL} statement, if one, being performed when the exception occurred.
* @param sqlException The {@code SQLException} to be converted
* @param message An optional error message
* @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);

View File

@ -12,24 +12,21 @@ import java.sql.SQLException;
import org.hibernate.JDBCException;
/**
* Defines a contract for implementations that know how to convert a
* {@link SQLException} to Hibernate's {@link JDBCException} hierarchy.
* <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.
* An object that interprets JDBC {@link SQLException}s and converts
* them to subtypes of Hibernate {@link JDBCException}s.
*
* @author Steve Ebersole
*/
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 message An optional error message.
* @return The resulting JDBCException.
* @param sqlException The {@code SQLException} to be converted
* @param message An optional error message
* @param sql The SQL statement that resulted in the exception
*
* @return The resulting {@code JDBCException}.
*
* @see org.hibernate.exception.ConstraintViolationException
* @see org.hibernate.exception.JDBCConnectionException

View File

@ -10,15 +10,15 @@ import java.sql.SQLException;
import java.util.function.Function;
/**
* Knows how to extract a violated constraint name from an error message based on the
* fact that the constraint name is templated within the message.
* Extracts a violated database constraint name from an error message
* by matching the error message against a template.
*
* @author Steve Ebersole
* @author Brett Meyer
*/
public class TemplatedViolatedConstraintNameExtractor implements ViolatedConstraintNameExtractor {
private Function<SQLException,String> extractConstraintName;
private final Function<SQLException,String> extractConstraintName;
public TemplatedViolatedConstraintNameExtractor(Function<SQLException,String> 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 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;
/**
* Defines a contract for implementations that can extract the name of a violated
* constraint from a {@link SQLException} that is the result of that constraint
* violation.
* An object that can extract the name of a violated database constraint
* from a {@link SQLException} that results from the constraint violation.
*
* @author Steve Ebersole
*/
@FunctionalInterface
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.
* @return The extracted constraint name.