diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java b/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java index c4274953b3..d873a4af7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java @@ -6,6 +6,8 @@ */ package org.hibernate.annotations; +import org.hibernate.jdbc.Expectation; + /** * Enumerates strategies for checking JDBC return codes for custom SQL DML queries. *
@@ -19,13 +21,20 @@ package org.hibernate.annotations; * @see SQLUpdate#check() * @see SQLDelete#check() * @see SQLDeleteAll#check() + * + * @see Expectation + * + * @deprecated Use an {@link Expectation} class instead. */ +@Deprecated(since = "6.5") public enum ResultCheckStyle { /** * 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 * example, by a {@link java.sql.CallableStatement stored procedure} which * performs explicit checks. + * + * @see org.hibernate.jdbc.Expectation.None */ NONE, /** @@ -34,6 +43,8 @@ public enum ResultCheckStyle { * {@link java.sql.Statement#executeBatch()}. The row count is checked * against an expected value. For example, the expected row count for * an {@code INSERT} statement is always 1. + * + * @see org.hibernate.jdbc.Expectation.RowCount */ COUNT, /** @@ -42,6 +53,8 @@ public enum ResultCheckStyle { * stored procedure}. *
* Statement batching is disabled when {@code PARAM} is selected.
+ *
+ * @see org.hibernate.jdbc.Expectation.OutParameter
*/
PARAM
}
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java
index 94c4e3451e..aebdd5f840 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java
@@ -6,6 +6,8 @@
*/
package org.hibernate.annotations;
+import org.hibernate.jdbc.Expectation;
+
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -42,8 +44,20 @@ public @interface SQLDelete {
boolean callable() default false;
/**
- * For persistence operation what style of determining results (success/failure) is to be used.
+ * An {@link Expectation} class used to verify that the operation was successful.
+ *
+ * @see Expectation.None
+ * @see Expectation.RowCount
+ * @see Expectation.OutParameter
*/
+ Class extends Expectation> verify() default Expectation.class;
+
+ /**
+ * A {@link ResultCheckStyle} used to verify that the operation was successful.
+ *
+ * @deprecated use {@link #verify()} with an {@link Expectation} class
+ */
+ @Deprecated(since = "6.5")
ResultCheckStyle check() default ResultCheckStyle.NONE;
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
index bbe20bfa07..9785dbbd5a 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
@@ -6,6 +6,8 @@
*/
package org.hibernate.annotations;
+import org.hibernate.jdbc.Expectation;
+
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -34,8 +36,20 @@ public @interface SQLDeleteAll {
boolean callable() default false;
/**
- * For persistence operation what style of determining results (success/failure) is to be used.
+ * An {@link Expectation} class used to verify that the operation was successful.
+ *
+ * @see Expectation.None
+ * @see Expectation.RowCount
+ * @see Expectation.OutParameter
*/
+ Class extends Expectation> verify() default Expectation.class;
+
+ /**
+ * A {@link ResultCheckStyle} used to verify that the operation was successful.
+ *
+ * @deprecated use {@link #verify()} with an {@link Expectation} class
+ */
+ @Deprecated(since = "6.5")
ResultCheckStyle check() default ResultCheckStyle.NONE;
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java
index a2a5b878ce..5d57a1a476 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java
@@ -6,6 +6,8 @@
*/
package org.hibernate.annotations;
+import org.hibernate.jdbc.Expectation;
+
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -58,8 +60,20 @@ public @interface SQLInsert {
boolean callable() default false;
/**
- * For persistence operation what style of determining results (success/failure) is to be used.
+ * An {@link Expectation} class used to verify that the operation was successful.
+ *
+ * @see Expectation.None
+ * @see Expectation.RowCount
+ * @see Expectation.OutParameter
*/
+ Class extends Expectation> verify() default Expectation.class;
+
+ /**
+ * A {@link ResultCheckStyle} used to verify that the operation was successful.
+ *
+ * @deprecated use {@link #verify()} with an {@link Expectation} class
+ */
+ @Deprecated(since = "6.5")
ResultCheckStyle check() default ResultCheckStyle.NONE;
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java
index 03340aeba4..1dceef81f2 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java
@@ -6,6 +6,8 @@
*/
package org.hibernate.annotations;
+import org.hibernate.jdbc.Expectation;
+
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -61,8 +63,20 @@ public @interface SQLUpdate {
boolean callable() default false;
/**
- * For persistence operation what style of determining results (success/failure) is to be used.
+ * An {@link Expectation} class used to verify that the operation was successful.
+ *
+ * @see Expectation.None
+ * @see Expectation.RowCount
+ * @see Expectation.OutParameter
*/
+ Class extends Expectation> verify() default Expectation.class;
+
+ /**
+ * A {@link ResultCheckStyle} used to verify that the operation was successful.
+ *
+ * @deprecated use {@link #verify()} with an {@link Expectation} class
+ */
+ @Deprecated(since = "6.5")
ResultCheckStyle check() default ResultCheckStyle.NONE;
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
index 1ce1125f9c..f564e2d35f 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
@@ -65,6 +65,7 @@ import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Persister;
import org.hibernate.annotations.QueryCacheLayout;
+import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLDeleteAll;
import org.hibernate.annotations.SQLInsert;
@@ -95,6 +96,8 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.Expectations;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Backref;
import org.hibernate.mapping.CheckConstraint;
@@ -1321,6 +1324,7 @@ public abstract class CollectionBinder {
propertyHolder.addProperty( prop, declaringClass );
}
+ @SuppressWarnings("deprecation")
private void bindLoader() {
//SQL overriding
@@ -1331,7 +1335,9 @@ public abstract class CollectionBinder {
sqlInsert.callable(),
fromResultCheckStyle( sqlInsert.check() )
);
-
+ if ( sqlInsert.verify() != Expectation.class ) {
+ collection.setInsertExpectation( sqlInsert.verify() );
+ }
}
final SQLUpdate sqlUpdate = property.getAnnotation( SQLUpdate.class );
@@ -1341,6 +1347,9 @@ public abstract class CollectionBinder {
sqlUpdate.callable(),
fromResultCheckStyle( sqlUpdate.check() )
);
+ if ( sqlUpdate.verify() != Expectation.class ) {
+ collection.setUpdateExpectation( sqlUpdate.verify() );
+ }
}
final SQLDelete sqlDelete = property.getAnnotation( SQLDelete.class );
@@ -1350,6 +1359,9 @@ public abstract class CollectionBinder {
sqlDelete.callable(),
fromResultCheckStyle( sqlDelete.check() )
);
+ if ( sqlDelete.verify() != Expectation.class ) {
+ collection.setDeleteExpectation( sqlDelete.verify() );
+ }
}
final SQLDeleteAll sqlDeleteAll = property.getAnnotation( SQLDeleteAll.class );
@@ -1359,6 +1371,9 @@ public abstract class CollectionBinder {
sqlDeleteAll.callable(),
fromResultCheckStyle( sqlDeleteAll.check() )
);
+ if ( sqlDeleteAll.verify() != Expectation.class ) {
+ collection.setDeleteAllExpectation( sqlDeleteAll.verify() );
+ }
}
final SQLSelect sqlSelect = property.getAnnotation( SQLSelect.class );
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
index 4b74698384..9938efee39 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
@@ -90,6 +90,7 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.CheckConstraint;
@@ -1387,7 +1388,9 @@ public class EntityBinder {
sqlInsert.callable(),
fromResultCheckStyle( sqlInsert.check() )
);
-
+ if ( sqlInsert.verify() != Expectation.class ) {
+ persistentClass.setInsertExpectation( sqlInsert.verify() );
+ }
}
final SQLUpdate sqlUpdate = findMatchingSqlAnnotation( "", SQLUpdate.class, SQLUpdates.class );
@@ -1397,6 +1400,9 @@ public class EntityBinder {
sqlUpdate.callable(),
fromResultCheckStyle( sqlUpdate.check() )
);
+ if ( sqlUpdate.verify() != Expectation.class ) {
+ persistentClass.setUpdateExpectation( sqlUpdate.verify() );
+ }
}
final SQLDelete sqlDelete = findMatchingSqlAnnotation( "", SQLDelete.class, SQLDeletes.class );
@@ -1406,6 +1412,9 @@ public class EntityBinder {
sqlDelete.callable(),
fromResultCheckStyle( sqlDelete.check() )
);
+ if ( sqlDelete.verify() != Expectation.class ) {
+ persistentClass.setDeleteExpectation( sqlDelete.verify() );
+ }
}
final SQLDeleteAll sqlDeleteAll = annotatedClass.getAnnotation( SQLDeleteAll.class );
@@ -2265,6 +2274,9 @@ public class EntityBinder {
sqlInsert.callable(),
fromResultCheckStyle( sqlInsert.check() )
);
+ if ( sqlInsert.verify() != Expectation.class ) {
+ join.setInsertExpectation( sqlInsert.verify() );
+ }
}
else if ( matchingTable != null ) {
final String insertSql = matchingTable.sqlInsert().sql();
@@ -2284,6 +2296,9 @@ public class EntityBinder {
sqlUpdate.callable(),
fromResultCheckStyle( sqlUpdate.check() )
);
+ if ( sqlUpdate.verify() != Expectation.class ) {
+ join.setUpdateExpectation( sqlUpdate.verify() );
+ }
}
else if ( matchingTable != null ) {
final String updateSql = matchingTable.sqlUpdate().sql();
@@ -2303,6 +2318,9 @@ public class EntityBinder {
sqlDelete.callable(),
fromResultCheckStyle( sqlDelete.check() )
);
+ if ( sqlDelete.verify() != Expectation.class ) {
+ join.setDeleteExpectation( sqlDelete.verify() );
+ }
}
else if ( matchingTable != null ) {
final String deleteSql = matchingTable.sqlDelete().sql();
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/ExecuteUpdateResultCheckStyle.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/ExecuteUpdateResultCheckStyle.java
index 89cb9cc78e..62bf4105dc 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/ExecuteUpdateResultCheckStyle.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/ExecuteUpdateResultCheckStyle.java
@@ -10,6 +10,7 @@ import org.hibernate.AssertionFailure;
import org.hibernate.annotations.ResultCheckStyle;
import org.checkerframework.checker.nullness.qual.Nullable;
+import org.hibernate.jdbc.Expectation;
/**
* For persistence operations (INSERT, UPDATE, DELETE) what style of
@@ -21,7 +22,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* new {@code org.hibernate.ResultCheck} enum.
*
* @author Steve Ebersole
+ *
+ * @deprecated Use an {@link org.hibernate.jdbc.Expectation} class
*/
+@Deprecated(since = "6.5", forRemoval = true)
public enum ExecuteUpdateResultCheckStyle {
/**
* Do not perform checking. Either user simply does not want checking, or is
@@ -85,4 +89,26 @@ public enum ExecuteUpdateResultCheckStyle {
public static ExecuteUpdateResultCheckStyle determineDefault(@Nullable String customSql, boolean callable) {
return customSql != null && callable ? PARAM : COUNT;
}
+
+ public static @Nullable Class extends Expectation> expectationClass(@Nullable ExecuteUpdateResultCheckStyle style) {
+ if ( style == null ) {
+ return null;
+ }
+ else {
+ return style.expectationClass();
+ }
+ }
+
+ public Class extends Expectation> expectationClass() {
+ switch (this) {
+ case NONE:
+ return Expectation.None.class;
+ case COUNT:
+ return Expectation.RowCount.class;
+ case PARAM:
+ return Expectation.OutParameter.class;
+ default:
+ throw new AssertionFailure( "Unrecognized ExecuteUpdateResultCheckStyle");
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/Expectation.java b/hibernate-core/src/main/java/org/hibernate/jdbc/Expectation.java
index 54b32789f1..83d434b465 100644
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/Expectation.java
+++ b/hibernate-core/src/main/java/org/hibernate/jdbc/Expectation.java
@@ -5,13 +5,43 @@
* See the lgpl.txt file in the root directory or
+ * The two standard implementations are {@link RowCount} for
+ * row count checking, and {@link OutParameter} for checking
+ * the return code assigned to an output parameter of a
+ * {@link CallableStatement}. Custom implementations are
+ * permitted.
+ *
+ * An {@code Expectation} is usually selected via an annotation,
+ * for example:
+ *
+ * Statement batching is disabled when {@code OutParameter} is used.
+ *
+ * @since 6.5
+ */
+ class OutParameter implements Expectation {
+ @Override
+ public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql) {
+ final int result;
+ try {
+ result = toCallableStatement( statement ).getInt( parameterIndex() );
+ }
+ catch ( SQLException sqle ) {
+ sqlExceptionHelper.logExceptions( sqle, "Could not extract row count from CallableStatement" );
+ throw new GenericJDBCException( "Could not extract row count from CallableStatement", sqle );
+ }
+ if ( batchPosition < 0 ) {
+ checkNonBatched( expectedRowCount(), result, sql );
+ }
+ else {
+ checkBatched( expectedRowCount(), result, batchPosition, sql );
+ }
+ }
+
+ @Override
+ public int getNumberOfParametersUsed() {
+ return 1;
+ }
+
+ @Override
+ public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
+ toCallableStatement( statement ).registerOutParameter( parameterIndex(), Types.NUMERIC );
+ return 1;
+ }
+
+ @Override
+ public boolean canBeBatched() {
+ return false;
+ }
+
+ protected int parameterIndex() {
+ return 1;
+ }
+
+ protected int expectedRowCount() {
+ return 1;
+ }
+ }
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/Expectations.java b/hibernate-core/src/main/java/org/hibernate/jdbc/Expectations.java
index 0e287fa97a..2034c13a8a 100644
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/Expectations.java
+++ b/hibernate-core/src/main/java/org/hibernate/jdbc/Expectations.java
@@ -11,7 +11,10 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
+import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
+import org.hibernate.InstantiationException;
+import org.hibernate.Internal;
import org.hibernate.StaleStateException;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
@@ -27,85 +30,44 @@ import org.hibernate.internal.CoreMessageLogger;
public class Expectations {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( Expectations.class );
- private static final SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper( false );
-
- public static final int USUAL_EXPECTED_COUNT = 1;
- public static final int USUAL_PARAM_POSITION = 1;
-
+ static final SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper( false );
// Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ /**
+ * @deprecated Use {@link RowCount}
+ */
+ @Deprecated(since = "6.5")
public static class BasicExpectation implements Expectation {
- private final int expectedRowCount;
+ private final int expected;
protected BasicExpectation(int expectedRowCount) {
- this.expectedRowCount = expectedRowCount;
+ expected = expectedRowCount;
if ( expectedRowCount < 0 ) {
throw new IllegalArgumentException( "Expected row count must be greater than zero" );
}
}
- public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String statementSQL) {
- rowCount = determineRowCount( rowCount, statement );
+ @Override
+ public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql) {
+ final int result = determineRowCount( rowCount, statement );
if ( batchPosition < 0 ) {
- checkNonBatched( rowCount, statementSQL );
+ checkNonBatched( expected, result, sql );
}
else {
- checkBatched( rowCount, batchPosition, statementSQL );
+ checkBatched( expected, result, batchPosition, sql );
}
}
- private void checkBatched(int rowCount, int batchPosition, String statementSQL) {
- 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 ( expectedRowCount > rowCount ) {
- throw new StaleStateException(
- "Batch update returned unexpected row count from update ["
- + batchPosition + "]; actual row count: " + rowCount
- + "; expected: " + expectedRowCount + "; statement executed: "
- + statementSQL
- );
- }
- if ( expectedRowCount < rowCount ) {
- String msg = "Batch update returned unexpected row count from update [" +
- batchPosition + "]; actual row count: " + rowCount +
- "; expected: " + expectedRowCount;
- throw new BatchedTooManyRowsAffectedException( msg, expectedRowCount, rowCount, batchPosition );
- }
- }
- }
-
- private void checkNonBatched(int rowCount, String statementSQL) {
- if ( expectedRowCount > rowCount ) {
- throw new StaleStateException(
- "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
- + "; statement executed: " + statementSQL
- );
- }
- if ( expectedRowCount < rowCount ) {
- String msg = "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount;
- throw new TooManyRowsAffectedException( msg, expectedRowCount, rowCount );
- }
- }
-
- public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
- return 0;
- }
-
- public boolean canBeBatched() {
- return true;
- }
-
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;
@@ -140,39 +102,88 @@ public class Expectations {
throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
}
}
+ }
- private CallableStatement toCallableStatement(PreparedStatement statement) {
- if ( !(statement instanceof CallableStatement) ) {
- throw new HibernateException(
- "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass()
- );
- }
+ static CallableStatement toCallableStatement(PreparedStatement statement) {
+ if ( statement instanceof CallableStatement ) {
return (CallableStatement) statement;
}
+ else {
+ throw new HibernateException( "Expectation.OutParameter operates exclusively on CallableStatements: "
+ + statement.getClass() );
+ }
}
+ 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 checkNonBatched(int expected, int rowCount, String sql) {
+ if ( expected > rowCount ) {
+ throw new StaleStateException(
+ "Unexpected row count: " + rowCount + "; expected: " + 1
+ + "; statement executed: " + sql
+ );
+ }
+ if ( expected < rowCount ) {
+ String msg = "Unexpected row count: " + rowCount + "; expected: " + 1;
+ throw new TooManyRowsAffectedException( msg, 1, rowCount );
+ }
+ }
// Various Expectation instances ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- public static final Expectation NONE = new Expectation() {
- public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String statementSQL) {
- // explicitly doAfterTransactionCompletion no checking...
+ /**
+ * @deprecated Use {@link Expectation.None}
+ */
+ @Deprecated(since = "6.5")
+ public static final Expectation NONE = new Expectation.None();
+
+ /**
+ * @deprecated Use {@link Expectation.RowCount}
+ */
+ @Deprecated(since = "6.5")
+ public static final Expectation BASIC = new Expectation.RowCount();
+
+ /**
+ * @deprecated Use {@link Expectation.OutParameter}
+ */
+ @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;
}
-
- public int prepare(PreparedStatement statement) {
- return 0;
+ try {
+ return expectation.newInstance();
}
-
- public boolean canBeBatched() {
- return true;
+ catch ( Exception e ) {
+ throw new InstantiationException( "Could not instantiate Expectation", expectation, e );
}
- };
-
- public static final Expectation BASIC = new BasicExpectation( USUAL_EXPECTED_COUNT );
-
- public static final Expectation PARAM = new BasicParamExpectation( USUAL_EXPECTED_COUNT, USUAL_PARAM_POSITION );
-
+ }
+ @Deprecated(since = "6.5", forRemoval = true)
public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
switch ( style ) {
case NONE:
@@ -182,10 +193,19 @@ public class Expectations {
case PARAM:
return PARAM;
default:
- throw new HibernateException( "unknown check style : " + style );
+ throw new AssertionFailure( "unknown result check style: " + style );
}
}
private Expectations() {
}
+
+ // Unused, for removal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ @Deprecated(since = "6.5", forRemoval = true)
+ public static final int USUAL_EXPECTED_COUNT = 1;
+
+ @Deprecated(since = "6.5", forRemoval = true)
+ public static final int USUAL_PARAM_POSITION = 1;
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java
index 6a473913e3..1fb23f2d6a 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java
@@ -27,7 +27,7 @@ import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.FilterConfiguration;
import org.hibernate.internal.util.StringHelper;
-import org.hibernate.internal.util.collections.ArrayHelper;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.service.ServiceRegistry;
@@ -36,6 +36,9 @@ import org.hibernate.type.CustomCollectionType;
import org.hibernate.type.Type;
import org.hibernate.usertype.UserCollectionType;
+import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.expectationClass;
+
/**
* A mapping model object representing a collection. Subclasses specialize to particular kinds of collection.
*
@@ -104,6 +107,11 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
private String loaderName;
+ private Class extends Expectation> insertExpectation;
+ private Class extends Expectation> updateExpectation;
+ private Class extends Expectation> deleteExpectation;
+ private Class extends Expectation> deleteAllExpectation;
+
/**
* hbm.xml binding
*/
@@ -170,6 +178,10 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
this.customSQLDeleteAll = original.customSQLDeleteAll;
this.customDeleteAllCallable = original.customDeleteAllCallable;
this.deleteAllCheckStyle = original.deleteAllCheckStyle;
+ this.insertExpectation = original.insertExpectation;
+ this.updateExpectation = original.updateExpectation;
+ this.deleteExpectation = original.deleteExpectation;
+ this.deleteAllExpectation = original.deleteAllExpectation;
this.loaderName = original.loaderName;
}
@@ -577,11 +589,11 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
this.queryCacheLayout = queryCacheLayout;
}
-
public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
this.customSQLInsert = customSQLInsert;
this.customInsertCallable = callable;
this.insertCheckStyle = checkStyle;
+ this.insertExpectation = expectationClass( checkStyle );
}
public String getCustomSQLInsert() {
@@ -592,6 +604,10 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
return customInsertCallable;
}
+ /**
+ * @deprecated use {@link #getInsertExpectation()}
+ */
+ @Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
return insertCheckStyle;
}
@@ -600,6 +616,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
this.customSQLUpdate = customSQLUpdate;
this.customUpdateCallable = callable;
this.updateCheckStyle = checkStyle;
+ this.updateExpectation = expectationClass( checkStyle );
}
public String getCustomSQLUpdate() {
@@ -610,6 +627,10 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
return customUpdateCallable;
}
+ /**
+ * @deprecated use {@link #getUpdateExpectation()}
+ */
+ @Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
return updateCheckStyle;
}
@@ -618,6 +639,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
this.customSQLDelete = customSQLDelete;
this.customDeleteCallable = callable;
this.deleteCheckStyle = checkStyle;
+ this.deleteExpectation = expectationClass( checkStyle );
}
public String getCustomSQLDelete() {
@@ -628,6 +650,10 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
return customDeleteCallable;
}
+ /**
+ * @deprecated use {@link #getDeleteExpectation()}
+ */
+ @Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
return deleteCheckStyle;
}
@@ -639,6 +665,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
this.customSQLDeleteAll = customSQLDeleteAll;
this.customDeleteAllCallable = callable;
this.deleteAllCheckStyle = checkStyle;
+ this.deleteAllExpectation = expectationClass( checkStyle );
}
public String getCustomSQLDeleteAll() {
@@ -755,19 +782,19 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
}
@SuppressWarnings("rawtypes")
- public void setTypeParameters(java.util.Map parameterMap) {
- if ( parameterMap instanceof Properties ) {
- this.typeParameters = (Properties) parameterMap;
+ public void setTypeParameters(java.util.Map typeParameters) {
+ if ( typeParameters instanceof Properties ) {
+ this.typeParameters = (Properties) typeParameters;
}
else {
this.typeParameters = new Properties();
- typeParameters.putAll( parameterMap );
+ this.typeParameters.putAll( typeParameters );
}
}
@Override
public boolean[] getColumnInsertability() {
- return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+ return EMPTY_BOOLEAN_ARRAY;
}
@Override
@@ -777,7 +804,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
@Override
public boolean[] getColumnUpdateability() {
- return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+ return EMPTY_BOOLEAN_ARRAY;
}
@Override
@@ -848,4 +875,36 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
public Column getSoftDeleteColumn() {
return softDeleteColumn;
}
+
+ public Class extends Expectation> getInsertExpectation() {
+ return insertExpectation;
+ }
+
+ public void setInsertExpectation(Class extends Expectation> insertExpectation) {
+ this.insertExpectation = insertExpectation;
+ }
+
+ public Class extends Expectation> getUpdateExpectation() {
+ return updateExpectation;
+ }
+
+ public void setUpdateExpectation(Class extends Expectation> updateExpectation) {
+ this.updateExpectation = updateExpectation;
+ }
+
+ public Class extends Expectation> getDeleteExpectation() {
+ return deleteExpectation;
+ }
+
+ public void setDeleteExpectation(Class extends Expectation> deleteExpectation) {
+ this.deleteExpectation = deleteExpectation;
+ }
+
+ public Class extends Expectation> getDeleteAllExpectation() {
+ return deleteAllExpectation;
+ }
+
+ public void setDeleteAllExpectation(Class extends Expectation> deleteAllExpectation) {
+ this.deleteAllExpectation = deleteAllExpectation;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Join.java b/hibernate-core/src/main/java/org/hibernate/mapping/Join.java
index fb9c8b9008..fe7ddb6062 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/Join.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/Join.java
@@ -12,8 +12,11 @@ import java.util.Iterator;
import java.util.List;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.sql.Alias;
+import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.expectationClass;
+
/**
* A mapping model object representing some sort of auxiliary table, for
* example, an {@linkplain jakarta.persistence.JoinTable association table},
@@ -47,6 +50,10 @@ public class Join implements AttributeContainer, Serializable {
private boolean customDeleteCallable;
private ExecuteUpdateResultCheckStyle deleteCheckStyle;
+ private Class extends Expectation> insertExpectation;
+ private Class extends Expectation> updateExpectation;
+ private Class extends Expectation> deleteExpectation;
+
@Override
public void addProperty(Property property) {
properties.add( property );
@@ -133,6 +140,7 @@ public class Join implements AttributeContainer, Serializable {
this.customSQLInsert = customSQLInsert;
this.customInsertCallable = callable;
this.insertCheckStyle = checkStyle;
+ this.insertExpectation = expectationClass( checkStyle );
}
public String getCustomSQLInsert() {
@@ -143,16 +151,8 @@ public class Join implements AttributeContainer, Serializable {
return customInsertCallable;
}
- public void setInsertCheckStyle(ExecuteUpdateResultCheckStyle insertCheckStyle) {
- this.insertCheckStyle = insertCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getInsertCheckStyle() {
- return insertCheckStyle;
- }
-
/**
- * @deprecated use {@link #getInsertCheckStyle()}
+ * @deprecated use {@link #getInsertExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
@@ -163,6 +163,7 @@ public class Join implements AttributeContainer, Serializable {
this.customSQLUpdate = customSQLUpdate;
this.customUpdateCallable = callable;
this.updateCheckStyle = checkStyle;
+ this.updateExpectation = expectationClass( checkStyle );
}
public String getCustomSQLUpdate() {
@@ -173,16 +174,8 @@ public class Join implements AttributeContainer, Serializable {
return customUpdateCallable;
}
- public void setUpdateCheckStyle(ExecuteUpdateResultCheckStyle updateCheckStyle) {
- this.updateCheckStyle = updateCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getUpdateCheckStyle() {
- return updateCheckStyle;
- }
-
/**
- * @deprecated use {@link #getUpdateCheckStyle()}
+ * @deprecated use {@link #getUpdateExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
@@ -193,6 +186,7 @@ public class Join implements AttributeContainer, Serializable {
this.customSQLDelete = customSQLDelete;
this.customDeleteCallable = callable;
this.deleteCheckStyle = checkStyle;
+ this.deleteExpectation = expectationClass( checkStyle );
}
public String getCustomSQLDelete() {
@@ -203,16 +197,8 @@ public class Join implements AttributeContainer, Serializable {
return customDeleteCallable;
}
- public void setDeleteCheckStyle(ExecuteUpdateResultCheckStyle deleteCheckStyle) {
- this.deleteCheckStyle = deleteCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getDeleteCheckStyle() {
- return deleteCheckStyle;
- }
-
/**
- * @deprecated use {@link #getDeleteCheckStyle()}
+ * @deprecated use {@link #getDeleteExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
@@ -243,7 +229,32 @@ public class Join implements AttributeContainer, Serializable {
public boolean isOptional() {
return optional;
}
+
public void setOptional(boolean nullable) {
this.optional = nullable;
}
+
+ public Class extends Expectation> getInsertExpectation() {
+ return insertExpectation;
+ }
+
+ public void setInsertExpectation(Class extends Expectation> insertExpectation) {
+ this.insertExpectation = insertExpectation;
+ }
+
+ public Class extends Expectation> getUpdateExpectation() {
+ return updateExpectation;
+ }
+
+ public void setUpdateExpectation(Class extends Expectation> updateExpectation) {
+ this.updateExpectation = updateExpectation;
+ }
+
+ public Class extends Expectation> getDeleteExpectation() {
+ return deleteExpectation;
+ }
+
+ public void setDeleteExpectation(Class extends Expectation> deleteExpectation) {
+ this.deleteExpectation = deleteExpectation;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java
index 3f3d07b2ef..917e3cd85e 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java
@@ -19,7 +19,6 @@ import org.hibernate.Internal;
import org.hibernate.MappingException;
import org.hibernate.annotations.CacheLayout;
import org.hibernate.boot.Metadata;
-import org.hibernate.boot.model.CustomSql;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.ClassLoaderAccess;
import org.hibernate.boot.spi.MetadataBuildingContext;
@@ -28,6 +27,7 @@ import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.FilterConfiguration;
import org.hibernate.internal.util.collections.JoinedList;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.jpa.event.spi.CallbackDefinition;
@@ -43,6 +43,7 @@ import static java.util.Collections.unmodifiableList;
import static java.util.Comparator.comparing;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.internal.util.StringHelper.root;
+import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.expectationClass;
import static org.hibernate.mapping.MappingHelper.checkPropertyColumnDuplication;
import static org.hibernate.sql.Template.collectColumnNames;
@@ -120,6 +121,10 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
private Component declaredIdentifierMapper;
private OptimisticLockStyle optimisticLockStyle;
+ private Class extends Expectation> insertExpectation;
+ private Class extends Expectation> updateExpectation;
+ private Class extends Expectation> deleteExpectation;
+
private boolean isCached;
private CacheLayout queryCacheLayout;
@@ -793,20 +798,11 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
return properties;
}
- public void setCustomSqlInsert(CustomSql customSql) {
- if ( customSql != null ) {
- setCustomSQLInsert(
- customSql.getSql(),
- customSql.isCallable(),
- customSql.getCheckStyle()
- );
- }
- }
-
public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
this.customSQLInsert = customSQLInsert;
this.customInsertCallable = callable;
this.insertCheckStyle = checkStyle;
+ this.insertExpectation = expectationClass( checkStyle );
}
public String getCustomSQLInsert() {
@@ -817,36 +813,19 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
return customInsertCallable;
}
- public void setInsertCheckStyle(ExecuteUpdateResultCheckStyle insertCheckStyle) {
- this.insertCheckStyle = insertCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getInsertCheckStyle() {
- return insertCheckStyle;
- }
-
/**
- * @deprecated use {@link #getInsertCheckStyle()}
+ * @deprecated use {@link #getInsertExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
return insertCheckStyle;
}
- public void setCustomSqlUpdate(CustomSql customSql) {
- if ( customSql != null ) {
- setCustomSQLUpdate(
- customSql.getSql(),
- customSql.isCallable(),
- customSql.getCheckStyle()
- );
- }
- }
-
public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
this.customSQLUpdate = customSQLUpdate;
this.customUpdateCallable = callable;
this.updateCheckStyle = checkStyle;
+ this.updateExpectation = expectationClass( checkStyle );
}
public String getCustomSQLUpdate() {
@@ -857,36 +836,19 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
return customUpdateCallable;
}
- public void setUpdateCheckStyle(ExecuteUpdateResultCheckStyle updateCheckStyle) {
- this.updateCheckStyle = updateCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getUpdateCheckStyle() {
- return updateCheckStyle;
- }
-
/**
- * @deprecated use {@link #getUpdateCheckStyle()}
+ * @deprecated use {@link #getUpdateExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
return updateCheckStyle;
}
- public void setCustomSqlDelete(CustomSql customSql) {
- if ( customSql != null ) {
- setCustomSQLDelete(
- customSql.getSql(),
- customSql.isCallable(),
- customSql.getCheckStyle()
- );
- }
- }
-
public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
this.customSQLDelete = customSQLDelete;
this.customDeleteCallable = callable;
this.deleteCheckStyle = checkStyle;
+ this.deleteExpectation = expectationClass( checkStyle );
}
public String getCustomSQLDelete() {
@@ -897,16 +859,8 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
return customDeleteCallable;
}
- public void setDeleteCheckStyle(ExecuteUpdateResultCheckStyle deleteCheckStyle) {
- this.deleteCheckStyle = deleteCheckStyle;
- }
-
- public ExecuteUpdateResultCheckStyle getDeleteCheckStyle() {
- return deleteCheckStyle;
- }
-
/**
- * @deprecated use {@link #getDeleteCheckStyle()}
+ * @deprecated use {@link #getDeleteExpectation()}
*/
@Deprecated(since = "6.5", forRemoval = true)
public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
@@ -1307,4 +1261,28 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
}
return null;
}
+
+ public Class extends Expectation> getInsertExpectation() {
+ return insertExpectation;
+ }
+
+ public void setInsertExpectation(Class extends Expectation> insertExpectation) {
+ this.insertExpectation = insertExpectation;
+ }
+
+ public Class extends Expectation> getUpdateExpectation() {
+ return updateExpectation;
+ }
+
+ public void setUpdateExpectation(Class extends Expectation> updateExpectation) {
+ this.updateExpectation = updateExpectation;
+ }
+
+ public Class extends Expectation> getDeleteExpectation() {
+ return deleteExpectation;
+ }
+
+ public void setDeleteExpectation(Class extends Expectation> deleteExpectation) {
+ this.deleteExpectation = deleteExpectation;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
index a4d0734792..02f092a43e 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
@@ -45,7 +45,6 @@ import org.hibernate.engine.jdbc.mutation.internal.MutationQueryOptions;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.profile.internal.FetchProfileAffectee;
-import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@@ -58,7 +57,6 @@ import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jdbc.Expectation;
-import org.hibernate.jdbc.Expectations;
import org.hibernate.loader.ast.internal.CollectionElementLoaderByIndex;
import org.hibernate.loader.ast.internal.CollectionLoaderNamedQuery;
import org.hibernate.loader.ast.internal.CollectionLoaderSingleKey;
@@ -137,6 +135,7 @@ import org.hibernate.type.Type;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
+import static org.hibernate.jdbc.Expectations.createExpectation;
import static org.hibernate.sql.model.ModelMutationLogging.MODEL_MUTATION_LOGGER;
/**
@@ -1688,74 +1687,38 @@ public abstract class AbstractCollectionPersister
collectionBootDescriptor.isInverse(),
new MutationDetails(
MutationType.INSERT,
- determineExpectation(
- collectionBootDescriptor.getCustomSQLInsertCheckStyle(),
- collectionBootDescriptor.getCustomSQLInsert(),
- collectionBootDescriptor.isCustomInsertCallable()
- ),
+ createExpectation( collectionBootDescriptor.getInsertExpectation(),
+ collectionBootDescriptor.isCustomInsertCallable()),
collectionBootDescriptor.getCustomSQLInsert(),
collectionBootDescriptor.isCustomInsertCallable()
),
new MutationDetails(
MutationType.UPDATE,
- determineExpectation(
- collectionBootDescriptor.getCustomSQLUpdateCheckStyle(),
- collectionBootDescriptor.getCustomSQLUpdate(),
- collectionBootDescriptor.isCustomUpdateCallable()
- ),
+ createExpectation( collectionBootDescriptor.getUpdateExpectation(),
+ collectionBootDescriptor.isCustomUpdateCallable()),
collectionBootDescriptor.getCustomSQLUpdate(),
collectionBootDescriptor.isCustomUpdateCallable()
),
collectionBootDescriptor.getKey().isCascadeDeleteEnabled(),
new MutationDetails(
MutationType.DELETE,
- determineExpectation(
- collectionBootDescriptor.getCustomSQLDeleteAllCheckStyle(),
- collectionBootDescriptor.getCustomSQLDeleteAll(),
- collectionBootDescriptor.isCustomDeleteAllCallable(),
- Expectations.NONE
- ),
+ collectionBootDescriptor.isCustomDeleteAllCallable() || collectionBootDescriptor.getDeleteAllExpectation() != null
+ ? createExpectation( collectionBootDescriptor.getDeleteAllExpectation(),
+ collectionBootDescriptor.isCustomDeleteAllCallable() )
+ : new Expectation.None(),
collectionBootDescriptor.getCustomSQLDeleteAll(),
collectionBootDescriptor.isCustomDeleteAllCallable()
),
new MutationDetails(
MutationType.DELETE,
- determineExpectation(
- collectionBootDescriptor.getCustomSQLDeleteCheckStyle(),
- collectionBootDescriptor.getCustomSQLDelete(),
- collectionBootDescriptor.isCustomDeleteCallable()
- ),
+ createExpectation( collectionBootDescriptor.getDeleteExpectation(),
+ collectionBootDescriptor.isCustomDeleteCallable()),
collectionBootDescriptor.getCustomSQLDelete(),
collectionBootDescriptor.isCustomDeleteCallable()
)
);
}
- private static Expectation determineExpectation(
- ExecuteUpdateResultCheckStyle explicitStyle,
- String customSql,
- boolean customSqlCallable,
- Expectation fallback) {
- if ( explicitStyle != null ) {
- return Expectations.appropriateExpectation( explicitStyle );
- }
-
- if ( customSql == null ) {
- return fallback;
- }
-
- return Expectations.appropriateExpectation(
- ExecuteUpdateResultCheckStyle.determineDefault( customSql, customSqlCallable )
- );
- }
-
- private static Expectation determineExpectation(
- ExecuteUpdateResultCheckStyle explicitStyle,
- String customSql,
- boolean customSqlCallable) {
- return determineExpectation( explicitStyle, customSql, customSqlCallable, Expectations.BASIC );
- }
-
protected JdbcMutationOperation buildDeleteAllOperation(MutatingTableReference tableReference) {
if ( tableMapping.getDeleteDetails().getCustomSql() != null ) {
return buildCustomSqlDeleteAllOperation( tableReference );
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
index 9154b2a4c8..229b8b92d3 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
@@ -7,7 +7,6 @@
package org.hibernate.persister.entity;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -23,7 +22,6 @@ import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.collections.ArrayHelper;
@@ -52,7 +50,6 @@ import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.internal.SqlFragmentPredicate;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
-import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.tree.from.NamedTableReference;
import org.hibernate.sql.ast.tree.from.TableGroup;
@@ -61,8 +58,6 @@ import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
import org.hibernate.sql.ast.tree.from.UnknownTableReferenceException;
import org.hibernate.sql.model.ast.builder.MutationGroupBuilder;
import org.hibernate.sql.model.ast.builder.TableInsertBuilder;
-import org.hibernate.sql.results.graph.DomainResult;
-import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.CompositeType;
@@ -78,7 +73,7 @@ import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray;
import static org.hibernate.internal.util.collections.CollectionHelper.linkedMapOfSize;
import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;
-import static org.hibernate.jdbc.Expectations.appropriateExpectation;
+import static org.hibernate.jdbc.Expectations.createExpectation;
import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildEncapsulatedCompositeIdentifierMapping;
import static org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper.buildNonEncapsulatedCompositeIdentifierMapping;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
@@ -162,7 +157,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// Span of the tables directly mapped by this entity and super-classes, if any
private final int coreTableSpan;
private final int subclassCoreTableSpan;
- // only contains values for SecondaryTables, ie. not tables part of the "coreTableSpan"
+ // only contains values for SecondaryTables, i.e. not tables part of the "coreTableSpan"
private final boolean[] isNullableTable;
private final boolean[] isInverseTable;
@@ -409,28 +404,16 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
isInverseTable[jk] = false;
customSQLInsert[jk] = currentClass.getCustomSQLInsert();
- insertCallable[jk] = customSQLInsert[jk] != null && currentClass.isCustomInsertCallable();
- insertExpectations[jk] = appropriateExpectation(
- currentClass.getInsertCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[jk], insertCallable[jk] )
- : currentClass.getInsertCheckStyle()
- );
+ insertCallable[jk] = currentClass.isCustomInsertCallable();
+ insertExpectations[jk] = createExpectation( currentClass.getInsertExpectation(), insertCallable[jk] );
customSQLUpdate[jk] = currentClass.getCustomSQLUpdate();
- updateCallable[jk] = customSQLUpdate[jk] != null && currentClass.isCustomUpdateCallable();
- updateExpectations[jk] = appropriateExpectation(
- currentClass.getUpdateCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] )
- : currentClass.getUpdateCheckStyle()
- );
+ updateCallable[jk] = currentClass.isCustomUpdateCallable();
+ updateExpectations[jk] = createExpectation( currentClass.getUpdateExpectation(), updateCallable[jk] );
customSQLDelete[jk] = currentClass.getCustomSQLDelete();
- deleteCallable[jk] = customSQLDelete[jk] != null && currentClass.isCustomDeleteCallable();
- deleteExpectations[jk] = appropriateExpectation(
- currentClass.getDeleteCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] )
- : currentClass.getDeleteCheckStyle()
- );
+ deleteCallable[jk] = currentClass.isCustomDeleteCallable();
+ deleteExpectations[jk] = createExpectation( currentClass.getDeleteExpectation(), deleteCallable[jk] );
jk--;
currentClass = currentClass.getSuperclass();
@@ -446,28 +429,16 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
isNullableTable[j] = join.isOptional();
customSQLInsert[j] = join.getCustomSQLInsert();
- insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
- insertExpectations[j] = appropriateExpectation(
- join.getInsertCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
- : join.getInsertCheckStyle()
- );
+ insertCallable[j] = join.isCustomInsertCallable();
+ insertExpectations[j] = createExpectation( join.getInsertExpectation(), insertCallable[j] );
customSQLUpdate[j] = join.getCustomSQLUpdate();
- updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
- updateExpectations[j] = appropriateExpectation(
- join.getUpdateCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
- : join.getUpdateCheckStyle()
- );
+ updateCallable[j] = join.isCustomUpdateCallable();
+ updateExpectations[j] = createExpectation( join.getUpdateExpectation(), updateCallable[j] );
customSQLDelete[j] = join.getCustomSQLDelete();
- deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
- deleteExpectations[j] = appropriateExpectation(
- join.getDeleteCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
- : join.getDeleteCheckStyle()
- );
+ deleteCallable[j] = join.isCustomDeleteCallable();
+ deleteExpectations[j] = createExpectation( join.getDeleteExpectation(), deleteCallable[j] );
j++;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
index 460f3fdd67..aa48bd8769 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
@@ -18,7 +18,6 @@ import org.hibernate.Remove;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.collections.ArrayHelper;
@@ -49,7 +48,7 @@ import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray
import static org.hibernate.internal.util.collections.ArrayHelper.toIntArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray;
import static org.hibernate.internal.util.collections.CollectionHelper.toSmallMap;
-import static org.hibernate.jdbc.Expectations.appropriateExpectation;
+import static org.hibernate.jdbc.Expectations.createExpectation;
import static org.hibernate.persister.entity.DiscriminatorHelper.NOT_NULL_DISCRIMINATOR;
import static org.hibernate.persister.entity.DiscriminatorHelper.NULL_DISCRIMINATOR;
import static org.hibernate.sql.model.ast.builder.TableMutationBuilder.NULL;
@@ -170,28 +169,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
deleteExpectations = new Expectation[joinSpan];
customSQLInsert[0] = persistentClass.getCustomSQLInsert();
- insertCallable[0] = customSQLInsert[0] != null && persistentClass.isCustomInsertCallable();
- insertExpectations[0] = appropriateExpectation(
- persistentClass.getInsertCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[0], insertCallable[0] )
- : persistentClass.getInsertCheckStyle()
- );
+ insertCallable[0] = persistentClass.isCustomInsertCallable();
+ insertExpectations[0] = createExpectation( persistentClass.getInsertExpectation(), insertCallable[0] );
customSQLUpdate[0] = persistentClass.getCustomSQLUpdate();
- updateCallable[0] = customSQLUpdate[0] != null && persistentClass.isCustomUpdateCallable();
- updateExpectations[0] = appropriateExpectation(
- persistentClass.getUpdateCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[0], updateCallable[0] )
- : persistentClass.getUpdateCheckStyle()
- );
+ updateCallable[0] = persistentClass.isCustomUpdateCallable();
+ updateExpectations[0] = createExpectation( persistentClass.getUpdateExpectation(), updateCallable[0] );
customSQLDelete[0] = persistentClass.getCustomSQLDelete();
- deleteCallable[0] = customSQLDelete[0] != null && persistentClass.isCustomDeleteCallable();
- deleteExpectations[0] = appropriateExpectation(
- persistentClass.getDeleteCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[0], deleteCallable[0] )
- : persistentClass.getDeleteCheckStyle()
- );
+ deleteCallable[0] = persistentClass.isCustomDeleteCallable();
+ deleteExpectations[0] = createExpectation( persistentClass.getDeleteExpectation(), deleteCallable[0] );
// JOINS
@@ -207,28 +194,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() && dialect.supportsCascadeDelete();
customSQLInsert[j] = join.getCustomSQLInsert();
- insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
- insertExpectations[j] = appropriateExpectation(
- join.getInsertCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
- : join.getInsertCheckStyle()
- );
+ insertCallable[j] = join.isCustomInsertCallable();
+ insertExpectations[j] = createExpectation( join.getInsertExpectation(), insertCallable[j] );
customSQLUpdate[j] = join.getCustomSQLUpdate();
- updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
- updateExpectations[j] = appropriateExpectation(
- join.getUpdateCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
- : join.getUpdateCheckStyle()
- );
+ updateCallable[j] = join.isCustomUpdateCallable();
+ updateExpectations[j] = createExpectation( join.getUpdateExpectation(), updateCallable[j] );
customSQLDelete[j] = join.getCustomSQLDelete();
- deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
- deleteExpectations[j] = appropriateExpectation(
- join.getDeleteCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
- : join.getDeleteCheckStyle()
- );
+ deleteCallable[j] = join.isCustomDeleteCallable();
+ deleteExpectations[j] = createExpectation( join.getDeleteExpectation(), deleteCallable[j] );
keyColumnNames[j] = new String[join.getKey().getColumnSpan()];
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
index 680285ff98..01420cab10 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
@@ -30,7 +30,6 @@ import org.hibernate.boot.Metadata;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.StaticFilterAliasGenerator;
@@ -65,7 +64,7 @@ import org.hibernate.type.StandardBasicTypes;
import static org.hibernate.internal.util.collections.ArrayHelper.to2DStringArray;
import static org.hibernate.internal.util.collections.ArrayHelper.toStringArray;
-import static org.hibernate.jdbc.Expectations.appropriateExpectation;
+import static org.hibernate.jdbc.Expectations.createExpectation;
/**
* An {@link EntityPersister} implementing the
@@ -125,41 +124,20 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
subclassTableNames = new String[]{tableName};
//Custom SQL
- String sql;
- boolean callable;
- ExecuteUpdateResultCheckStyle checkStyle;
- sql = persistentClass.getCustomSQLInsert();
- callable = sql != null && persistentClass.isCustomInsertCallable();
- checkStyle = sql == null
- ? ExecuteUpdateResultCheckStyle.COUNT
- : persistentClass.getInsertCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
- : persistentClass.getInsertCheckStyle();
- customSQLInsert = new String[] {sql};
- insertCallable = new boolean[] {callable};
- insertExpectations = new Expectation[] { appropriateExpectation( checkStyle ) };
+ customSQLInsert = new String[] { persistentClass.getCustomSQLInsert() };
+ insertCallable = new boolean[] { persistentClass.isCustomInsertCallable() };
+ insertExpectations = new Expectation[] { createExpectation( persistentClass.getInsertExpectation(),
+ persistentClass.isCustomInsertCallable() ) };
- sql = persistentClass.getCustomSQLUpdate();
- callable = sql != null && persistentClass.isCustomUpdateCallable();
- checkStyle = sql == null
- ? ExecuteUpdateResultCheckStyle.COUNT
- : persistentClass.getUpdateCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
- : persistentClass.getUpdateCheckStyle();
- customSQLUpdate = new String[] {sql};
- updateCallable = new boolean[] {callable};
- updateExpectations = new Expectation[] { appropriateExpectation( checkStyle ) };
+ customSQLUpdate = new String[] { persistentClass.getCustomSQLUpdate() };
+ updateCallable = new boolean[] { persistentClass.isCustomUpdateCallable() };
+ updateExpectations = new Expectation[] { createExpectation( persistentClass.getUpdateExpectation(),
+ persistentClass.isCustomUpdateCallable() ) };
- sql = persistentClass.getCustomSQLDelete();
- callable = sql != null && persistentClass.isCustomDeleteCallable();
- checkStyle = sql == null
- ? ExecuteUpdateResultCheckStyle.COUNT
- : persistentClass.getDeleteCheckStyle() == null
- ? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
- : persistentClass.getDeleteCheckStyle();
- customSQLDelete = new String[] {sql};
- deleteCallable = new boolean[] {callable};
- deleteExpectations = new Expectation[] { appropriateExpectation( checkStyle ) };
+ customSQLDelete = new String[] { persistentClass.getCustomSQLDelete() };
+ deleteCallable = new boolean[] { persistentClass.isCustomDeleteCallable() };
+ deleteExpectations = new Expectation[] { createExpectation( persistentClass.getDeleteExpectation(),
+ persistentClass.isCustomDeleteCallable() ) };
discriminatorValue = persistentClass.getSubclassId();
discriminatorSQLValue = String.valueOf( persistentClass.getSubclassId() );
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hql/size/WhereClauseOrderBySizeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hql/size/WhereClauseOrderBySizeTest.java
index 96b8bb5a26..1d8ae2fcc5 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/hql/size/WhereClauseOrderBySizeTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hql/size/WhereClauseOrderBySizeTest.java
@@ -28,6 +28,7 @@ import org.hibernate.annotations.SQLRestriction;
import org.hibernate.annotations.Where;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.RequiresDialect;
@@ -141,7 +142,8 @@ public class WhereClauseOrderBySizeTest extends BaseEntityManagerFunctionalTestC
}
@Entity(name = "Book")
- @SQLDelete(sql = "UPDATE Book SET deleted = true WHERE id = ?", check = ResultCheckStyle.COUNT)
+ @SQLDelete(sql = "UPDATE Book SET deleted = true WHERE id = ?",
+ verify = Expectation.RowCount.class)
@SQLRestriction("deleted = false")
public static class Book {
@Id
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/typebinder/NoResultCheck.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/typebinder/NoResultCheck.java
index 1f9f35a0e0..969b261cff 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/typebinder/NoResultCheck.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/typebinder/NoResultCheck.java
@@ -3,6 +3,7 @@ package org.hibernate.orm.test.mapping.attributebinder.typebinder;
import org.hibernate.annotations.TypeBinderType;
import org.hibernate.binder.TypeBinder;
import org.hibernate.boot.spi.MetadataBuildingContext;
+import org.hibernate.jdbc.Expectation;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
@@ -11,7 +12,6 @@ import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.NONE;
@TypeBinderType(binder = NoResultCheck.Binder.class)
@Retention(RUNTIME)
@@ -20,9 +20,9 @@ public @interface NoResultCheck {
class Binder implements TypeBinder
+ * @Entity
+ * @SQLUpdate(sql = "update Record set uid = gen_random_uuid(), whatever = ? where id = ?",
+ * verify = Expectation.RowCount.class)
+ * class Record { ... }
+ *
+ *
+ * @see org.hibernate.annotations.SQLInsert#verify
+ * @see org.hibernate.annotations.SQLUpdate#verify
+ * @see org.hibernate.annotations.SQLDelete#verify
+ * @see org.hibernate.annotations.SQLDeleteAll#verify
*
* @author Steve Ebersole
*/
@@ -22,12 +52,14 @@ public interface Expectation {
*
* @return True if batching can be combined with this expectation; false otherwise.
*/
- boolean canBeBatched();
+ default boolean canBeBatched() {
+ return true;
+ }
/**
* The number of parameters this expectation implies. E.g.,
- * {@link Expectations.BasicParamExpectation} requires a single
- * OUT parameter for reading back the number of affected rows.
+ * {@link OutParameter} requires a single OUT parameter for
+ * reading back the number of affected rows.
*/
default int getNumberOfParametersUsed() {
return 0;
@@ -40,11 +72,12 @@ public interface Expectation {
* @param rowCount The RDBMS reported "number of rows affected".
* @param statement The statement representing the operation
* @param batchPosition The position in the batch (if batching)
- * @param statementSQL The SQL backing the prepared statement, for logging purposes
+ * @param sql The SQL backing the prepared statement, for logging purposes
* @throws SQLException Exception from the JDBC driver
* @throws HibernateException Problem processing the outcome.
*/
- void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String statementSQL) throws SQLException, HibernateException;
+ void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql)
+ throws SQLException, HibernateException;
/**
* Perform any special statement preparation.
@@ -54,5 +87,101 @@ public interface Expectation {
* @throws SQLException Exception from the JDBC driver
* @throws HibernateException Problem performing preparation.
*/
- int prepare(PreparedStatement statement) throws SQLException, HibernateException;
+ default int prepare(PreparedStatement statement) throws SQLException, HibernateException {
+ return 0;
+ }
+
+ /**
+ * 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
+ * example, by a {@link java.sql.CallableStatement stored procedure} which
+ * performs explicit checks.
+ *
+ * @since 6.5
+ */
+ class None implements Expectation {
+ @Override
+ public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql) {
+ // nothing to do
+ }
+ }
+
+ /**
+ * Row count checking. A row count is an integer value returned by
+ * {@link java.sql.PreparedStatement#executeUpdate()} or
+ * {@link java.sql.Statement#executeBatch()}. The row count is checked
+ * against an expected value. For example, the expected row count for
+ * an {@code INSERT} statement is always 1.
+ *
+ * @since 6.5
+ */
+ class RowCount implements Expectation {
+ @Override
+ public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition, String sql) {
+ if ( batchPosition < 0 ) {
+ checkNonBatched( expectedRowCount(), rowCount, sql );
+ }
+ else {
+ checkBatched( expectedRowCount(), rowCount, batchPosition, sql );
+ }
+ }
+
+ protected int expectedRowCount() {
+ return 1;
+ }
+ }
+
+ /**
+ * Essentially identical to {@link RowCount} except that the row count
+ * is obtained via an output parameter of a {@link CallableStatement
+ * stored procedure}.
+ *