@@ -573,7 +573,6 @@ public CodeBlock build() {
573573 return delete (builder , rowMapper , result , queryResultType , returnType , actualReturnType );
574574 } else {
575575
576- // TODO: Projection
577576 String resultSetExtractor = null ;
578577
579578 if (rowMapperClass != null ) {
@@ -583,8 +582,17 @@ public CodeBlock build() {
583582 builder .addStatement ("$T $L = $L.getRowMapper($S)" , RowMapper .class , rowMapper ,
584583 context .fieldNameOf (RowMapperFactory .class ), rowMapperRef );
585584 } else if (resultSetExtractorClass == null ) {
585+
586+ Type typeToRead ;
587+
588+ if (isProjecting ) {
589+ typeToRead = context .getReturnedType ().getDomainType ();
590+ } else {
591+ typeToRead = context .getActualReturnType ().getType ();
592+ }
593+
586594 builder .addStatement ("$T $L = $L.create($T.class)" , RowMapper .class , rowMapper ,
587- context .fieldNameOf (RowMapperFactory .class ), actualReturnType );
595+ context .fieldNameOf (RowMapperFactory .class ), typeToRead );
588596 }
589597
590598 if (StringUtils .hasText (resultSetExtractorRef ) || resultSetExtractorClass != null ) {
@@ -611,6 +619,9 @@ public CodeBlock build() {
611619 return builder .build ();
612620 }
613621
622+ boolean dynamicProjection = StringUtils .hasText (context .getDynamicProjectionParameterName ());
623+ Object queryResultTypeRef = dynamicProjection ? context .getDynamicProjectionParameterName () : queryResultType ;
624+
614625 if (queryMethod .isCollectionQuery () || queryMethod .isSliceQuery () || queryMethod .isPageQuery ()) {
615626
616627 builder .addStatement ("$1T $2L = ($1T) getJdbcOperations().query($3L, $4L, new $5T<>($6L))" , List .class ,
@@ -620,8 +631,9 @@ public CodeBlock build() {
620631
621632 String pageable = context .getPageableParameterName ();
622633
623- builder .addStatement ("$1T $2L = ($1T) convertMany($3L, $4T.class)" , List .class ,
624- context .localVariable ("converted" ), result , queryResultType );
634+ builder .addStatement (
635+ "$1T $2L = ($1T) convertMany($3L, %s)" .formatted (dynamicProjection ? "$4L" : "$4T.class" ), List .class ,
636+ context .localVariable ("converted" ), result , queryResultTypeRef );
625637
626638 if (queryMethod .isPageQuery ()) {
627639
@@ -639,94 +651,28 @@ public CodeBlock build() {
639651 return builder .build ();
640652 }
641653
642- builder .addStatement ("return ($T) convertMany($L, $ T.class)" , context . getReturnTypeName (), result ,
643- queryResultType );
654+ builder .addStatement ("return ($T) convertMany($L, %s)" . formatted ( dynamicProjection ? "$L" : "$ T.class" ) ,
655+ context . getReturnTypeName (), result , queryResultTypeRef );
644656 } else if (queryMethod .isStreamQuery ()) {
645657
646658 builder .addStatement ("$1T $2L = getJdbcOperations().queryForStream($3L, $4L, $5L)" , Stream .class , result ,
647659 queryVariableName , parameterSourceVariableName , rowMapper );
648660 builder .addStatement ("return ($T) convertMany($L, $T.class)" , context .getReturnTypeName (), result ,
649- queryResultType );
661+ queryResultTypeRef );
650662 } else {
651663
652664 builder .addStatement ("$T $L = queryForObject($L, $L, $L)" , Object .class , result , queryVariableName ,
653665 parameterSourceVariableName , rowMapper );
654666
655667 if (Optional .class .isAssignableFrom (context .getReturnType ().toClass ())) {
656- builder .addStatement ("return ($1T) $1T.ofNullable(convertOne($2L, $3T.class))" , Optional .class , result ,
657- queryResultType );
668+ builder .addStatement (
669+ "return ($1T) $1T.ofNullable(convertOne($2L, %s))" .formatted (dynamicProjection ? "$3L" : "$3T.class" ),
670+ Optional .class , result , queryResultTypeRef );
658671 } else {
659- builder .addStatement ("return ($T) convertOne($L, $ T.class)" , context . getReturnTypeName (), result ,
660- queryResultType );
672+ builder .addStatement ("return ($T) convertOne($L, %s)" . formatted ( dynamicProjection ? "$L" : "$ T.class" ) ,
673+ context . getReturnTypeName (), result , queryResultTypeRef );
661674 }
662675 }
663-
664- /* if (context.getReturnedType().isProjecting()) {
665-
666- if (queryMethod.isCollectionQuery()) {
667- builder.addStatement("return ($T) convertMany($L.getResultList(), $L, $T.class)",
668- context.getReturnTypeName(), queryVariableName, aotQuery.isNative(), queryResultType);
669- } else if (queryMethod.isStreamQuery()) {
670- builder.addStatement("return ($T) convertMany($L.getResultStream(), $L, $T.class)",
671- context.getReturnTypeName(), queryVariableName, aotQuery.isNative(), queryResultType);
672- } else if (queryMethod.isPageQuery()) {
673- builder.addStatement("return $T.getPage(($T<$T>) convertMany($L.getResultList(), $L, $T.class), $L, $L)",
674- PageableExecutionUtils.class, List.class, actualReturnType, queryVariableName, aotQuery.isNative(),
675- queryResultType, pageable, context.localVariable("countAll"));
676- } else if (queryMethod.isSliceQuery()) {
677- builder.addStatement("$T<$T> $L = ($T<$T>) convertMany($L.getResultList(), $L, $T.class)", List.class,
678- actualReturnType, context.localVariable("resultList"), List.class, actualReturnType, queryVariableName,
679- aotQuery.isNative(), queryResultType);
680- builder.addStatement("boolean $L = $L.isPaged() && $L.size() > $L.getPageSize()",
681- context.localVariable("hasNext"), pageable, context.localVariable("resultList"), pageable);
682- builder.addStatement("return new $T<>($L ? $L.subList(0, $L.getPageSize()) : $L, $L, $L)", SliceImpl.class,
683- context.localVariable("hasNext"), context.localVariable("resultList"), pageable,
684- context.localVariable("resultList"), pageable, context.localVariable("hasNext"));
685- } else {
686-
687- if (Optional.class.isAssignableFrom(context.getReturnType().toClass())) {
688- builder.addStatement("return $T.ofNullable(($T) convertOne($L.getSingleResultOrNull(), $L, $T.class))",
689- Optional.class, actualReturnType, queryVariableName, aotQuery.isNative(), queryResultType);
690- } else {
691- builder.addStatement("return ($T) convertOne($L.getSingleResultOrNull(), $L, $T.class)",
692- context.getReturnTypeName(), queryVariableName, aotQuery.isNative(), queryResultType);
693- }
694- }
695-
696- } else {
697-
698- if(resultSetExtractor != null){
699-
700- }
701-
702- if (queryMethod.isCollectionQuery()) {
703- builder.addStatement("return ($T) $L.getResultList()", context.getReturnTypeName(), queryVariableName);
704- } else if (queryMethod.isStreamQuery()) {
705- builder.addStatement("return ($T) $L.getResultStream()", context.getReturnTypeName(), queryVariableName);
706- } else if (queryMethod.isPageQuery()) {
707- builder.addStatement("return $T.getPage(($T<$T>) $L.getResultList(), $L, $L)", PageableExecutionUtils.class,
708- List.class, actualReturnType, queryVariableName, pageable, context.localVariable("countAll"));
709- } else if (queryMethod.isSliceQuery()) {
710- builder.addStatement("$T<$T> $L = $L.getResultList()", List.class, actualReturnType,
711- context.localVariable("resultList"), queryVariableName);
712- builder.addStatement("boolean $L = $L.isPaged() && $L.size() > $L.getPageSize()",
713- context.localVariable("hasNext"), pageable, context.localVariable("resultList"), pageable);
714- builder.addStatement("return new $T<>($L ? $L.subList(0, $L.getPageSize()) : $L, $L, $L)", SliceImpl.class,
715- context.localVariable("hasNext"), context.localVariable("resultList"), pageable,
716- context.localVariable("resultList"), pageable, context.localVariable("hasNext"));
717- } else {
718-
719- if (Optional.class.isAssignableFrom(context.getReturnType().toClass())) {
720- builder.addStatement("return $T.ofNullable(($T) convertOne($L.getSingleResultOrNull(), $L, $T.class))",
721- Optional.class, actualReturnType, queryVariableName, aotQuery.isNative(),
722- context.getActualReturnType().toClass());
723- } else {
724- builder.addStatement("return ($T) convertOne($L.getSingleResultOrNull(), $L, $T.class)",
725- context.getReturnTypeName(), queryVariableName, aotQuery.isNative(),
726- context.getReturnType().toClass());
727- }
728- }
729- } */
730676 }
731677
732678 return builder .build ();
0 commit comments