5555import org .springframework .data .cassandra .core .query .Query ;
5656import org .springframework .data .domain .Slice ;
5757import org .springframework .data .mapping .callback .EntityCallbacks ;
58+ import org .springframework .data .projection .EntityProjection ;
5859import org .springframework .data .projection .ProjectionFactory ;
5960import org .springframework .data .projection .SpelAwareProxyProjectionFactory ;
6061import org .springframework .lang .Nullable ;
@@ -115,8 +116,6 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP
115116
116117 private final EntityOperations entityOperations ;
117118
118- private final SpelAwareProxyProjectionFactory projectionFactory ;
119-
120119 private final StatementFactory statementFactory ;
121120
122121 private @ Nullable ApplicationEventPublisher eventPublisher ;
@@ -182,8 +181,7 @@ public CassandraTemplate(CqlOperations cqlOperations, CassandraConverter convert
182181
183182 this .converter = converter ;
184183 this .cqlOperations = cqlOperations ;
185- this .entityOperations = new EntityOperations (converter .getMappingContext ());
186- this .projectionFactory = new SpelAwareProxyProjectionFactory ();
184+ this .entityOperations = new EntityOperations (converter );
187185 this .statementFactory = new StatementFactory (new QueryMapper (converter ), new UpdateMapper (converter ));
188186 }
189187
@@ -212,9 +210,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
212210 if (entityCallbacks == null ) {
213211 setEntityCallbacks (EntityCallbacks .create (applicationContext ));
214212 }
215-
216- projectionFactory .setBeanFactory (applicationContext );
217- projectionFactory .setBeanClassLoader (applicationContext .getClassLoader ());
218213 }
219214
220215 /**
@@ -287,9 +282,10 @@ protected EntityOperations getEntityOperations() {
287282 * projections.
288283 * @see org.springframework.data.projection.SpelAwareProxyProjectionFactory
289284 * @since 2.1
285+ * @deprecated since 3.4, use {@link CassandraConverter#getProjectionFactory()} instead.
290286 */
291287 protected SpelAwareProxyProjectionFactory getProjectionFactory () {
292- return this . projectionFactory ;
288+ return ( SpelAwareProxyProjectionFactory ) getConverter (). getProjectionFactory () ;
293289 }
294290
295291 private CassandraPersistentEntity <?> getRequiredPersistentEntity (Class <?> entityType ) {
@@ -378,7 +374,8 @@ public <T> List<T> select(Statement<?> statement, Class<T> entityClass) {
378374 Assert .notNull (statement , "Statement must not be null" );
379375 Assert .notNull (entityClass , "Entity type must not be null" );
380376
381- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
377+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
378+ EntityQueryUtils .getTableName (statement ));
382379
383380 return doQuery (statement , (row , rowNum ) -> mapper .apply (row ));
384381 }
@@ -404,7 +401,8 @@ public <T> Slice<T> slice(Statement<?> statement, Class<T> entityClass) {
404401
405402 ResultSet resultSet = doQueryForResultSet (statement );
406403
407- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
404+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
405+ EntityQueryUtils .getTableName (statement ));
408406
409407 return EntityQueryUtils .readSlice (resultSet , (row , rowNum ) -> mapper .apply (row ), 0 ,
410408 getEffectivePageSize (statement ));
@@ -419,7 +417,8 @@ public <T> Stream<T> stream(Statement<?> statement, Class<T> entityClass) throws
419417 Assert .notNull (statement , "Statement must not be null" );
420418 Assert .notNull (entityClass , "Entity type must not be null" );
421419
422- Function <Row , T > mapper = getMapper (entityClass , entityClass , EntityQueryUtils .getTableName (statement ));
420+ Function <Row , T > mapper = getMapper (EntityProjection .nonProjecting (entityClass ),
421+ EntityQueryUtils .getTableName (statement ));
423422 return doQueryForStream (statement , (row , rowNum ) -> mapper .apply (row ));
424423 }
425424
@@ -442,14 +441,14 @@ public <T> List<T> select(Query query, Class<T> entityClass) throws DataAccessEx
442441 <T > List <T > doSelect (Query query , Class <?> entityClass , CqlIdentifier tableName , Class <T > returnType ) {
443442
444443 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 );
447447
448448 Query queryToUse = query .columns (columns );
449449
450450 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 );
453452
454453 return doQuery (select .build (), (row , rowNum ) -> mapper .apply (row ));
455454 }
@@ -495,8 +494,9 @@ <T> Stream<T> doStream(Query query, Class<?> entityClass, CqlIdentifier tableNam
495494
496495 StatementBuilder <Select > select = getStatementFactory ().select (query , getRequiredPersistentEntity (entityClass ),
497496 tableName );
497+ EntityProjection <T , ?> projection = entityOperations .introspectProjection (returnType , entityClass );
498498
499- Function <Row , T > mapper = getMapper (entityClass , returnType , tableName );
499+ Function <Row , T > mapper = getMapper (projection , tableName );
500500 return doQueryForStream (select .build (), (row , rowNum ) -> mapper .apply (row ));
501501 }
502502
@@ -639,7 +639,7 @@ public <T> T selectOneById(Object id, Class<T> entityClass) {
639639 CassandraPersistentEntity <?> entity = getRequiredPersistentEntity (entityClass );
640640 CqlIdentifier tableName = entity .getTableName ();
641641 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 );
643643 List <T > result = doQuery (select .build (), (row , rowNum ) -> mapper .apply (row ));
644644
645645 return result .isEmpty () ? null : result .get (0 );
@@ -999,17 +999,15 @@ public String getCql() {
999999 }
10001000
10011001 @ 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 ) {
10031003
1004- Class <?> typeToRead = resolveTypeToRead ( entityType , targetType );
1004+ Class <T > targetType = projection . getMappedType (). getType ( );
10051005
10061006 return row -> {
10071007
10081008 maybeEmitEvent (new AfterLoadEvent <>(row , targetType , tableName ));
10091009
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 );
10131011
10141012 if (result != null ) {
10151013 maybeEmitEvent (new AfterConvertEvent <>(row , result , tableName ));
@@ -1019,10 +1017,6 @@ private <T> Function<Row, T> getMapper(Class<?> entityType, Class<T> targetType,
10191017 };
10201018 }
10211019
1022- private Class <?> resolveTypeToRead (Class <?> entityType , Class <?> targetType ) {
1023- return targetType .isInterface () || targetType .isAssignableFrom (entityType ) ? entityType : targetType ;
1024- }
1025-
10261020 private static MappingCassandraConverter newConverter (CqlSession session ) {
10271021
10281022 MappingCassandraConverter converter = new MappingCassandraConverter ();
0 commit comments