HHH-15587 some enhancements and cleanups to Expectations stuff
This commit is contained in:
parent
a1c26f54bf
commit
bf1c37b722
|
@ -12,6 +12,7 @@ import java.sql.SQLException;
|
|||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.exception.GenericJDBCException;
|
||||
|
||||
import static org.hibernate.jdbc.Expectations.checkBatched;
|
||||
|
@ -91,6 +92,20 @@ public interface Expectation {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that this implementation is compatible with the kind of
|
||||
* {@link PreparedStatement} it will be called with. Implementors
|
||||
* should throw a {@link MappingException} if the configuration
|
||||
* is not supported.
|
||||
*
|
||||
* @param callable true if this {@code Expectation} will be called
|
||||
* with a {@link CallableStatement}.
|
||||
*
|
||||
* @since 6.5
|
||||
*/
|
||||
default void validate(boolean callable) throws MappingException {
|
||||
}
|
||||
|
||||
/**
|
||||
* No return code checking. Might mean that no checks are required, or that
|
||||
* failure is indicated by a {@link java.sql.SQLException} being thrown, for
|
||||
|
@ -159,6 +174,13 @@ public interface Expectation {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(boolean callable) throws MappingException {
|
||||
if ( !callable ) {
|
||||
throw new MappingException( "Expectation.OutParameter operates exclusively on CallableStatements" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfParametersUsed() {
|
||||
return 1;
|
||||
|
|
|
@ -8,8 +8,6 @@ package org.hibernate.jdbc;
|
|||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -18,12 +16,14 @@ import org.hibernate.Internal;
|
|||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||
import org.hibernate.exception.GenericJDBCException;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import static java.sql.Statement.EXECUTE_FAILED;
|
||||
import static java.sql.Statement.SUCCESS_NO_INFO;
|
||||
|
||||
/**
|
||||
* Holds various often used {@link Expectation} definitions.
|
||||
* Useful operations for dealing with {@link Expectation}s.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -32,76 +32,28 @@ public class Expectations {
|
|||
|
||||
static final SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper( false );
|
||||
|
||||
// Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RowCount}
|
||||
* Create an instance of the given class implementing {@link Expectation}.
|
||||
* @param expectation a class which implements {@code Expectation}
|
||||
* @param callable true if the {@code Expectation} will be called with {@link CallableStatement}s.
|
||||
* @return a new instance of the given class
|
||||
*
|
||||
* @since 6.5
|
||||
*/
|
||||
@Deprecated(since = "6.5")
|
||||
public static class BasicExpectation implements Expectation {
|
||||
private final int expected;
|
||||
|
||||
protected BasicExpectation(int expectedRowCount) {
|
||||
expected = expectedRowCount;
|
||||
if ( expectedRowCount < 0 ) {
|
||||
throw new IllegalArgumentException( "Expected row count must be greater than zero" );
|
||||
}
|
||||
@Internal
|
||||
public static Expectation createExpectation(Class<? extends Expectation> expectation, boolean callable) {
|
||||
if ( expectation == null ) {
|
||||
expectation = callable ? Expectation.OutParameter.class : Expectation.RowCount.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql) {
|
||||
final int result = determineRowCount( rowCount, statement );
|
||||
if ( batchPosition < 0 ) {
|
||||
checkNonBatched( expected, result, sql );
|
||||
}
|
||||
else {
|
||||
checkBatched( expected, result, batchPosition, sql );
|
||||
}
|
||||
final Expectation instance;
|
||||
try {
|
||||
instance = expectation.newInstance();
|
||||
}
|
||||
|
||||
protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
|
||||
return reportedRowCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link OutParameter}
|
||||
*/
|
||||
@Deprecated(since = "6.5")
|
||||
public static class BasicParamExpectation extends BasicExpectation {
|
||||
private final int parameterPosition;
|
||||
|
||||
protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
|
||||
super( expectedRowCount );
|
||||
this.parameterPosition = parameterPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfParametersUsed() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
|
||||
toCallableStatement( statement ).registerOutParameter( parameterPosition, Types.NUMERIC );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeBatched() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
|
||||
try {
|
||||
return toCallableStatement( statement ).getInt( parameterPosition );
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
sqlExceptionHelper.logExceptions( sqle, "could not extract row counts from CallableStatement" );
|
||||
throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new InstantiationException( "Could not instantiate Expectation", expectation, e );
|
||||
}
|
||||
instance.validate(callable);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static CallableStatement toCallableStatement(PreparedStatement statement) {
|
||||
|
@ -114,39 +66,90 @@ public class Expectations {
|
|||
}
|
||||
}
|
||||
|
||||
static void checkBatched(int expected, int rowCount, int batchPosition, String sql) {
|
||||
if ( rowCount == -2 ) {
|
||||
LOG.debugf( "Success of batch update unknown: %s", batchPosition );
|
||||
}
|
||||
else if ( rowCount == -3 ) {
|
||||
throw new BatchFailedException( "Batch update failed: " + batchPosition );
|
||||
}
|
||||
else if ( expected > rowCount ) {
|
||||
throw new StaleStateException(
|
||||
"Batch update returned unexpected row count from update ["
|
||||
+ batchPosition + "]; actual row count: " + rowCount
|
||||
+ "; expected: " + 1 + "; statement executed: "
|
||||
+ sql
|
||||
);
|
||||
}
|
||||
else if ( expected < rowCount ) {
|
||||
String msg = "Batch update returned unexpected row count from update [" +
|
||||
batchPosition + "]; actual row count: " + rowCount +
|
||||
"; expected: " + 1;
|
||||
throw new BatchedTooManyRowsAffectedException( msg, 1, rowCount, batchPosition );
|
||||
static void checkBatched(int expectedRowCount, int rowCount, int batchPosition, String sql) {
|
||||
switch (rowCount) {
|
||||
case EXECUTE_FAILED:
|
||||
throw new BatchFailedException( "Batch update failed: " + batchPosition );
|
||||
case SUCCESS_NO_INFO:
|
||||
LOG.debugf( "Success of batch update unknown: %s", batchPosition );
|
||||
break;
|
||||
default:
|
||||
if ( expectedRowCount > rowCount ) {
|
||||
throw new StaleStateException(
|
||||
"Batch update returned unexpected row count from update ["
|
||||
+ batchPosition + "]; actual row count: " + rowCount
|
||||
+ "; expected: " + expectedRowCount + "; statement executed: "
|
||||
+ sql
|
||||
);
|
||||
}
|
||||
else if ( expectedRowCount < rowCount ) {
|
||||
throw new BatchedTooManyRowsAffectedException(
|
||||
"Batch update returned unexpected row count from update [" +
|
||||
batchPosition + "]; actual row count: " + rowCount +
|
||||
"; expected: " + expectedRowCount,
|
||||
expectedRowCount, rowCount, batchPosition );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkNonBatched(int expected, int rowCount, String sql) {
|
||||
if ( expected > rowCount ) {
|
||||
static void checkNonBatched(int expectedRowCount, int rowCount, String sql) {
|
||||
if ( expectedRowCount > rowCount ) {
|
||||
throw new StaleStateException(
|
||||
"Unexpected row count: " + rowCount + "; expected: " + 1
|
||||
"Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
|
||||
+ "; statement executed: " + sql
|
||||
);
|
||||
}
|
||||
if ( expected < rowCount ) {
|
||||
String msg = "Unexpected row count: " + rowCount + "; expected: " + 1;
|
||||
throw new TooManyRowsAffectedException( msg, 1, rowCount );
|
||||
if ( expectedRowCount < rowCount ) {
|
||||
throw new TooManyRowsAffectedException(
|
||||
"Unexpected row count: " + rowCount + "; expected: " + expectedRowCount,
|
||||
1, rowCount
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RowCount}, creating a custom subclass if necessary
|
||||
*/
|
||||
@Deprecated(since = "6.5")
|
||||
public static class BasicExpectation extends Expectation.RowCount {
|
||||
private final int expectedRowCount;
|
||||
|
||||
protected BasicExpectation(int expectedRowCount) {
|
||||
this.expectedRowCount = expectedRowCount;
|
||||
if ( expectedRowCount < 0 ) {
|
||||
throw new IllegalArgumentException( "Expected row count must be greater than zero" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int expectedRowCount() {
|
||||
return expectedRowCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link OutParameter}, creating a custom subclass if necessary
|
||||
*/
|
||||
@Deprecated(since = "6.5")
|
||||
public static class BasicParamExpectation extends Expectation.OutParameter {
|
||||
private final int parameterPosition;
|
||||
private final int expectedRowCount;
|
||||
|
||||
protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
|
||||
this.expectedRowCount = expectedRowCount;
|
||||
this.parameterPosition = parameterPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int expectedRowCount() {
|
||||
return expectedRowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int parameterIndex() {
|
||||
return parameterPosition;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,19 +173,6 @@ public class Expectations {
|
|||
@Deprecated(since = "6.5")
|
||||
public static final Expectation PARAM = new Expectation.OutParameter();
|
||||
|
||||
@Internal
|
||||
public static Expectation createExpectation(Class<? extends Expectation> expectation, boolean callable) {
|
||||
if ( expectation == null ) {
|
||||
expectation = callable ? Expectation.OutParameter.class : Expectation.RowCount.class;
|
||||
}
|
||||
try {
|
||||
return expectation.newInstance();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new InstantiationException( "Could not instantiate Expectation", expectation, e );
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(since = "6.5", forRemoval = true)
|
||||
public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
|
||||
switch ( style ) {
|
||||
|
|
Loading…
Reference in New Issue