55
55
import org .springframework .data .cassandra .core .query .Query ;
56
56
import org .springframework .data .domain .Slice ;
57
57
import org .springframework .data .mapping .callback .EntityCallbacks ;
58
+ import org .springframework .data .projection .EntityProjection ;
58
59
import org .springframework .data .projection .ProjectionFactory ;
59
60
import org .springframework .data .projection .SpelAwareProxyProjectionFactory ;
60
61
import org .springframework .lang .Nullable ;
@@ -115,8 +116,6 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP
115
116
116
117
private final EntityOperations entityOperations ;
117
118
118
- private final SpelAwareProxyProjectionFactory projectionFactory ;
119
-
120
119
private final StatementFactory statementFactory ;
121
120
122
121
private @ Nullable ApplicationEventPublisher eventPublisher ;
@@ -182,8 +181,7 @@ public CassandraTemplate(CqlOperations cqlOperations, CassandraConverter convert
182
181
183
182
this .converter = converter ;
184
183
this .cqlOperations = cqlOperations ;
185
- this .entityOperations = new EntityOperations (converter .getMappingContext ());
186
- this .projectionFactory = new SpelAwareProxyProjectionFactory ();
184
+ this .entityOperations = new EntityOperations (converter );
187
185
this .statementFactory = new StatementFactory (new QueryMapper (converter ), new UpdateMapper (converter ));
188
186
}
189
187
@@ -212,9 +210,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
212
210
if (entityCallbacks == null ) {
213
211
setEntityCallbacks (EntityCallbacks .create (applicationContext ));
214
212
}
215
-
216
- projectionFactory .setBeanFactory (applicationContext );
217
- projectionFactory .setBeanClassLoader (applicationContext .getClassLoader ());
218
213
}
219
214
220
215
/**
@@ -287,9 +282,10 @@ protected EntityOperations getEntityOperations() {
287
282
* projections.
288
283
* @see org.springframework.data.projection.SpelAwareProxyProjectionFactory
289
284
* @since 2.1
285
+ * @deprecated since 3.4, use {@link CassandraConverter#getProjectionFactory()} instead.
290
286
*/
291
287
protected SpelAwareProxyProjectionFactory getProjectionFactory () {
292
- return this . projectionFactory ;
288
+ return ( SpelAwareProxyProjectionFactory ) getConverter (). getProjectionFactory () ;
293
289
}
294
290
295
291
private CassandraPersistentEntity <?> getRequiredPersistentEntity (Class <?> entityType ) {
@@ -378,7 +374,8 @@ public <T> List<T> select(Statement<?> statement, Class<T> entityClass) {
378
374
Assert .notNull (statement , "Statement must not be null" );
379
375
Assert .notNull (entityClass , "Entity type must not be null" );
380
376
381
- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
377
+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
378
+ EntityQueryUtils .getTableName (statement ));
382
379
383
380
return doQuery (statement , (row , rowNum ) -> mapper .apply (row ));
384
381
}
@@ -404,7 +401,8 @@ public <T> Slice<T> slice(Statement<?> statement, Class<T> entityClass) {
404
401
405
402
ResultSet resultSet = doQueryForResultSet (statement );
406
403
407
- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
404
+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
405
+ EntityQueryUtils .getTableName (statement ));
408
406
409
407
return EntityQueryUtils .readSlice (resultSet , (row , rowNum ) -> mapper .apply (row ), 0 ,
410
408
getEffectivePageSize (statement ));
@@ -419,7 +417,8 @@ public <T> Stream<T> stream(Statement<?> statement, Class<T> entityClass) throws
419
417
Assert .notNull (statement , "Statement must not be null" );
420
418
Assert .notNull (entityClass , "Entity type must not be null" );
421
419
422
- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
420
+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
421
+ EntityQueryUtils .getTableName (statement ));
423
422
return doQueryForStream (statement , (row , rowNum ) -> mapper .apply (row ));
424
423
}
425
424
@@ -442,14 +441,14 @@ public <T> List<T> select(Query query, Class<T> entityClass) throws DataAccessEx
442
441
<T > List <T > doSelect (Query query , Class <?> entityClass , CqlIdentifier tableName , Class <T > returnType ) {
443
442
444
443
CassandraPersistentEntity <?> entity = getRequiredPersistentEntity (entityClass );
445
-
446
- Columns columns = getStatementFactory ().computeColumnsForProjection (query .getColumns (), entity , returnType );
444
+ EntityProjection <T , ?> projection = entityOperations .introspectProjection (returnType , entityClass );
445
+ Columns columns = getStatementFactory ().computeColumnsForProjection (projection , query .getColumns (), entity ,
446
+ returnType );
447
447
448
448
Query queryToUse = query .columns (columns );
449
449
450
450
StatementBuilder <Select > select = getStatementFactory ().select (queryToUse , entity , tableName );
451
-
452
- Function <Row , T > mapper = getMapper (entityClass , returnType , tableName );
451
+ Function <Row , T > mapper = getMapper (projection , tableName );
453
452
454
453
return doQuery (select .build (), (row , rowNum ) -> mapper .apply (row ));
455
454
}
@@ -495,8 +494,9 @@ <T> Stream<T> doStream(Query query, Class<?> entityClass, CqlIdentifier tableNam
495
494
496
495
StatementBuilder <Select > select = getStatementFactory ().select (query , getRequiredPersistentEntity (entityClass ),
497
496
tableName );
497
+ EntityProjection <T , ?> projection = entityOperations .introspectProjection (returnType , entityClass );
498
498
499
- Function <Row , T > mapper = getMapper (entityClass , returnType , tableName );
499
+ Function <Row , T > mapper = getMapper (projection , tableName );
500
500
return doQueryForStream (select .build (), (row , rowNum ) -> mapper .apply (row ));
501
501
}
502
502
@@ -639,7 +639,7 @@ public <T> T selectOneById(Object id, Class<T> entityClass) {
639
639
CassandraPersistentEntity <?> entity = getRequiredPersistentEntity (entityClass );
640
640
CqlIdentifier tableName = entity .getTableName ();
641
641
StatementBuilder <Select > select = getStatementFactory ().selectOneById (id , entity , tableName );
642
- Function <Row , T > mapper = getMapper (entityClass , entityClass , tableName );
642
+ Function <Row , T > mapper = getMapper (EntityProjection . nonProjecting ( entityClass ) , tableName );
643
643
List <T > result = doQuery (select .build (), (row , rowNum ) -> mapper .apply (row ));
644
644
645
645
return result .isEmpty () ? null : result .get (0 );
@@ -999,17 +999,15 @@ public String getCql() {
999
999
}
1000
1000
1001
1001
@ SuppressWarnings ("unchecked" )
1002
- private <T > Function <Row , T > getMapper (Class <?> entityType , Class < T > targetType , CqlIdentifier tableName ) {
1002
+ private <T > Function <Row , T > getMapper (EntityProjection < T , ?> projection , CqlIdentifier tableName ) {
1003
1003
1004
- Class <?> typeToRead = resolveTypeToRead ( entityType , targetType );
1004
+ Class <T > targetType = projection . getMappedType (). getType ( );
1005
1005
1006
1006
return row -> {
1007
1007
1008
1008
maybeEmitEvent (new AfterLoadEvent <>(row , targetType , tableName ));
1009
1009
1010
- Object source = getConverter ().read (typeToRead , row );
1011
-
1012
- T result = (T ) (targetType .isInterface () ? getProjectionFactory ().createProjection (targetType , source ) : source );
1010
+ T result = getConverter ().project (projection , row );
1013
1011
1014
1012
if (result != null ) {
1015
1013
maybeEmitEvent (new AfterConvertEvent <>(row , result , tableName ));
@@ -1019,10 +1017,6 @@ private <T> Function<Row, T> getMapper(Class<?> entityType, Class<T> targetType,
1019
1017
};
1020
1018
}
1021
1019
1022
- private Class <?> resolveTypeToRead (Class <?> entityType , Class <?> targetType ) {
1023
- return targetType .isInterface () || targetType .isAssignableFrom (entityType ) ? entityType : targetType ;
1024
- }
1025
-
1026
1020
private static MappingCassandraConverter newConverter (CqlSession session ) {
1027
1021
1028
1022
MappingCassandraConverter converter = new MappingCassandraConverter ();
0 commit comments