17
17
18
18
import java .util .Collections ;
19
19
import java .util .List ;
20
+ import java .util .concurrent .CompletionStage ;
20
21
import java .util .function .Consumer ;
21
22
import java .util .function .Function ;
22
23
import java .util .stream .Collectors ;
33
34
import org .springframework .dao .DataAccessException ;
34
35
import org .springframework .dao .OptimisticLockingFailureException ;
35
36
import org .springframework .dao .support .DataAccessUtils ;
37
+ import org .springframework .dao .support .PersistenceExceptionTranslator ;
36
38
import org .springframework .data .cassandra .SessionFactory ;
37
39
import org .springframework .data .cassandra .core .EntityOperations .AdaptibleEntity ;
38
40
import org .springframework .data .cassandra .core .convert .CassandraConverter ;
@@ -822,6 +824,19 @@ public ListenableFuture<Void> truncate(Class<?> entityClass) {
822
824
// Implementation hooks and utility methods
823
825
// -------------------------------------------------------------------------
824
826
827
+ /**
828
+ * Create a new statement-based {@link AsyncPreparedStatementHandler} using the statement passed in.
829
+ * <p>
830
+ * This method allows for the creation to be overridden by subclasses.
831
+ *
832
+ * @param statement the statement to be prepared.
833
+ * @return the new {@link PreparedStatementHandler} to use.
834
+ * @since 3.3.3
835
+ */
836
+ protected AsyncPreparedStatementHandler createPreparedStatementHandler (Statement <?> statement ) {
837
+ return new PreparedStatementHandler (statement , exceptionTranslator );
838
+ }
839
+
825
840
private <T > ListenableFuture <EntityWriteResult <T >> executeSave (T entity , CqlIdentifier tableName ,
826
841
SimpleStatement statement ) {
827
842
@@ -874,7 +889,7 @@ private <T> ListenableFuture<List<T>> doQuery(Statement<?> statement, RowMapper<
874
889
875
890
if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
876
891
877
- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
892
+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
878
893
return getAsyncCqlOperations ().query (statementHandler , statementHandler , rowMapper );
879
894
}
880
895
@@ -885,7 +900,7 @@ private ListenableFuture<Void> doQuery(Statement<?> statement, RowCallbackHandle
885
900
886
901
if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
887
902
888
- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
903
+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
889
904
return getAsyncCqlOperations ().query (statementHandler , statementHandler , callbackHandler );
890
905
}
891
906
@@ -900,7 +915,7 @@ private <T> ListenableFuture<T> doExecute(Statement<?> statement, Function<Async
900
915
901
916
if (PreparedStatementDelegate .canPrepare (isUsePreparedStatements (), statement , log )) {
902
917
903
- PreparedStatementHandler statementHandler = new PreparedStatementHandler (statement );
918
+ AsyncPreparedStatementHandler statementHandler = createPreparedStatementHandler (statement );
904
919
return getAsyncCqlOperations ().query (statementHandler , statementHandler ,
905
920
(AsyncResultSetExtractor <T >) resultSet -> new AsyncResult <>(mappingFunction .apply (resultSet )));
906
921
}
@@ -1021,19 +1036,33 @@ protected T adapt(@Nullable S adapteeResult) {
1021
1036
}
1022
1037
}
1023
1038
1039
+ /**
1040
+ * General callback interface used to create and bind prepared CQL statements.
1041
+ * <p>
1042
+ * This interface prepares the CQL statement and sets values on a {@link PreparedStatement} as union-type comprised
1043
+ * from {@link AsyncPreparedStatementCreator}, {@link PreparedStatementBinder}, and {@link CqlProvider}.
1044
+ *
1045
+ * @since 3.3.3
1046
+ */
1047
+ public interface AsyncPreparedStatementHandler
1048
+ extends AsyncPreparedStatementCreator , PreparedStatementBinder , CqlProvider {
1049
+
1050
+ }
1051
+
1024
1052
/**
1025
1053
* Utility class to prepare a {@link SimpleStatement} and bind values associated with the statement to a
1026
1054
* {@link BoundStatement}.
1027
1055
*
1028
1056
* @since 3.2
1029
1057
*/
1030
- private class PreparedStatementHandler
1031
- implements AsyncPreparedStatementCreator , PreparedStatementBinder , CqlProvider {
1058
+ public static class PreparedStatementHandler implements AsyncPreparedStatementHandler {
1032
1059
1033
1060
private final SimpleStatement statement ;
1061
+ private final PersistenceExceptionTranslator exceptionTranslator ;
1034
1062
1035
- public PreparedStatementHandler (Statement <?> statement ) {
1063
+ public PreparedStatementHandler (Statement <?> statement , PersistenceExceptionTranslator exceptionTranslator ) {
1036
1064
this .statement = PreparedStatementDelegate .getStatementForPrepare (statement );
1065
+ this .exceptionTranslator = exceptionTranslator ;
1037
1066
}
1038
1067
1039
1068
/*
@@ -1042,7 +1071,17 @@ public PreparedStatementHandler(Statement<?> statement) {
1042
1071
*/
1043
1072
@ Override
1044
1073
public ListenableFuture <PreparedStatement > createPreparedStatement (CqlSession session ) throws DriverException {
1045
- return new CassandraFutureAdapter <>(session .prepareAsync (statement ), exceptionTranslator );
1074
+ return new CassandraFutureAdapter <>(doPrepare (session ), exceptionTranslator );
1075
+ }
1076
+
1077
+ /**
1078
+ * Invokes the statement preparation.
1079
+ *
1080
+ * @param session
1081
+ * @return
1082
+ */
1083
+ protected CompletionStage <PreparedStatement > doPrepare (CqlSession session ) {
1084
+ return session .prepareAsync (statement );
1046
1085
}
1047
1086
1048
1087
/*
0 commit comments