1717
1818import java .util .Collections ;
1919import java .util .List ;
20+ import java .util .concurrent .CompletionStage ;
2021import java .util .function .Consumer ;
2122import java .util .function .Function ;
2223import java .util .stream .Collectors ;
3334import org .springframework .dao .DataAccessException ;
3435import org .springframework .dao .OptimisticLockingFailureException ;
3536import org .springframework .dao .support .DataAccessUtils ;
37+ import org .springframework .dao .support .PersistenceExceptionTranslator ;
3638import org .springframework .data .cassandra .SessionFactory ;
3739import org .springframework .data .cassandra .core .EntityOperations .AdaptibleEntity ;
3840import org .springframework .data .cassandra .core .convert .CassandraConverter ;
@@ -729,6 +731,19 @@ public ListenableFuture<Void> truncate(Class<?> entityClass) {
729731 // Implementation hooks and utility methods
730732 // -------------------------------------------------------------------------
731733
734+ /**
735+ * Create a new statement-based {@link AsyncPreparedStatementHandler} using the statement passed in.
736+ * <p>
737+ * This method allows for the creation to be overridden by subclasses.
738+ *
739+ * @param statement the statement to be prepared.
740+ * @return the new {@link PreparedStatementHandler} to use.
741+ * @since 3.3.3
742+ */
743+ protected AsyncPreparedStatementHandler createPreparedStatementHandler (Statement <?> statement ) {
744+ return new PreparedStatementHandler (statement , exceptionTranslator );
745+ }
746+
732747 private <T > ListenableFuture <EntityWriteResult <T >> executeSave (T entity , CqlIdentifier tableName ,
733748 SimpleStatement statement ) {
734749
@@ -781,7 +796,7 @@ private <T> ListenableFuture<List<T>> doQuery(Statement<?> statement, RowMapper<
781796
782797 if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
783798
784- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
799+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
785800 return getAsyncCqlOperations ().query (statementHandler , statementHandler , rowMapper );
786801 }
787802
@@ -792,7 +807,7 @@ private ListenableFuture<Void> doQuery(Statement<?> statement, RowCallbackHandle
792807
793808 if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
794809
795- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
810+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
796811 return getAsyncCqlOperations ().query (statementHandler , statementHandler , callbackHandler );
797812 }
798813
@@ -807,7 +822,7 @@ private <T> ListenableFuture<T> doExecute(Statement<?> statement, Function<Async
807822
808823 if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
809824
810- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
825+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
811826 return getAsyncCqlOperations ().query (statementHandler , statementHandler ,
812827 (AsyncResultSetExtractor <T >) resultSet -> new AsyncResult <>(mappingFunction .apply (resultSet )));
813828 }
@@ -925,24 +940,48 @@ protected T adapt(@Nullable S adapteeResult) {
925940 }
926941 }
927942
943+ /**
944+ * General callback interface used to create and bind prepared CQL statements.
945+ * <p>
946+ * This interface prepares the CQL statement and sets values on a {@link PreparedStatement} as union-type comprised
947+ * from {@link AsyncPreparedStatementCreator}, {@link PreparedStatementBinder}, and {@link CqlProvider}.
948+ *
949+ * @since 3.3.3
950+ */
951+ public interface AsyncPreparedStatementHandler
952+ extends AsyncPreparedStatementCreator , PreparedStatementBinder , CqlProvider {
953+
954+ }
955+
928956 /**
929957 * Utility class to prepare a {@link SimpleStatement} and bind values associated with the statement to a
930958 * {@link BoundStatement}.
931959 *
932960 * @since 3.2
933961 */
934- private class PreparedStatementHandler
935- implements AsyncPreparedStatementCreator , PreparedStatementBinder , CqlProvider {
962+ public static class PreparedStatementHandler implements AsyncPreparedStatementHandler {
936963
937964 private final SimpleStatement statement ;
965+ private final PersistenceExceptionTranslator exceptionTranslator ;
938966
939- public PreparedStatementHandler (Statement <?> statement ) {
967+ public PreparedStatementHandler (Statement <?> statement , PersistenceExceptionTranslator exceptionTranslator ) {
940968 this .statement = PreparedStatementDelegate .getStatementForPrepare (statement );
969+ this .exceptionTranslator = exceptionTranslator ;
941970 }
942971
943972 @ Override
944973 public ListenableFuture <PreparedStatement > createPreparedStatement (CqlSession session ) throws DriverException {
945- return new CassandraFutureAdapter <>(session .prepareAsync (statement ), exceptionTranslator );
974+ return new CassandraFutureAdapter <>(doPrepare (session ), exceptionTranslator );
975+ }
976+
977+ /**
978+ * Invokes the statement preparation.
979+ *
980+ * @param session
981+ * @return
982+ */
983+ protected CompletionStage <PreparedStatement > doPrepare (CqlSession session ) {
984+ return session .prepareAsync (statement );
946985 }
947986
948987 @ Override
0 commit comments