1818import static org .springframework .data .mongodb .repository .aot .MongoCodeBlocks .*;
1919import static org .springframework .data .mongodb .repository .aot .QueryBlocks .*;
2020
21+ import java .io .IOException ;
2122import java .lang .reflect .Method ;
23+ import java .util .Properties ;
2224
2325import org .apache .commons .logging .Log ;
2426import org .apache .commons .logging .LogFactory ;
2527import org .jspecify .annotations .Nullable ;
2628
2729import org .springframework .core .annotation .AnnotatedElementUtils ;
30+ import org .springframework .core .io .support .PathMatchingResourcePatternResolver ;
2831import org .springframework .data .mongodb .core .MongoOperations ;
2932import org .springframework .data .mongodb .core .aggregation .AggregationUpdate ;
3033import org .springframework .data .mongodb .core .convert .MongoCustomConversions ;
3134import org .springframework .data .mongodb .core .mapping .MongoMappingContext ;
3235import org .springframework .data .mongodb .repository .Query ;
3336import org .springframework .data .mongodb .repository .Update ;
3437import org .springframework .data .mongodb .repository .VectorSearch ;
38+ import org .springframework .data .mongodb .repository .config .MongoRepositoryConfigurationExtension ;
3539import org .springframework .data .mongodb .repository .query .MongoQueryMethod ;
3640import org .springframework .data .repository .aot .generate .AotRepositoryClassBuilder ;
3741import org .springframework .data .repository .aot .generate .AotRepositoryConstructorBuilder ;
3842import org .springframework .data .repository .aot .generate .MethodContributor ;
3943import org .springframework .data .repository .aot .generate .QueryMetadata ;
4044import org .springframework .data .repository .aot .generate .RepositoryContributor ;
4145import org .springframework .data .repository .config .AotRepositoryContext ;
46+ import org .springframework .data .repository .config .PropertiesBasedNamedQueriesFactoryBean ;
47+ import org .springframework .data .repository .config .RepositoryConfigurationSource ;
48+ import org .springframework .data .repository .core .NamedQueries ;
4249import org .springframework .data .repository .core .RepositoryInformation ;
50+ import org .springframework .data .repository .core .support .PropertiesBasedNamedQueries ;
4351import org .springframework .data .repository .core .support .RepositoryFactoryBeanSupport ;
4452import org .springframework .data .repository .query .QueryMethod ;
4553import org .springframework .data .repository .query .parser .PartTree ;
@@ -61,11 +69,18 @@ public class MongoRepositoryContributor extends RepositoryContributor {
6169
6270 private final AotQueryCreator queryCreator ;
6371 private final MongoMappingContext mappingContext ;
72+ private final NamedQueries namedQueries ;
6473
6574 public MongoRepositoryContributor (AotRepositoryContext repositoryContext ) {
6675
6776 super (repositoryContext );
6877
78+ ClassLoader classLoader = repositoryContext .getBeanFactory () != null ? repositoryContext .getClassLoader () : null ;
79+ if (classLoader == null ) {
80+ classLoader = getClass ().getClassLoader ();
81+ }
82+ namedQueries = getNamedQueries (repositoryContext .getConfigurationSource (), classLoader );
83+
6984 // avoid Java Time (JSR-310) Type introspection
7085 MongoCustomConversions mongoCustomConversions = MongoCustomConversions
7186 .create (MongoCustomConversions .MongoConverterConfigurationAdapter ::useNativeDriverJavaTimeCodecs );
@@ -78,6 +93,32 @@ public MongoRepositoryContributor(AotRepositoryContext repositoryContext) {
7893 this .queryCreator = new AotQueryCreator (this .mappingContext );
7994 }
8095
96+ private NamedQueries getNamedQueries (@ Nullable RepositoryConfigurationSource configSource , ClassLoader classLoader ) {
97+
98+ String location = configSource != null ? configSource .getNamedQueryLocation ().orElse (null ) : null ;
99+
100+ if (location == null ) {
101+ location = new MongoRepositoryConfigurationExtension ().getDefaultNamedQueryLocation ();
102+ }
103+
104+ if (StringUtils .hasText (location )) {
105+
106+ try {
107+
108+ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver (classLoader );
109+
110+ PropertiesBasedNamedQueriesFactoryBean factoryBean = new PropertiesBasedNamedQueriesFactoryBean ();
111+ factoryBean .setLocations (resolver .getResources (location ));
112+ factoryBean .afterPropertiesSet ();
113+ return factoryBean .getObject ();
114+ } catch (IOException e ) {
115+ throw new RuntimeException (e );
116+ }
117+ }
118+
119+ return new PropertiesBasedNamedQueries (new Properties ());
120+ }
121+
81122 @ Override
82123 protected void customizeClass (AotRepositoryClassBuilder classBuilder ) {
83124 classBuilder .customize (builder -> builder .superclass (TypeName .get (MongoAotRepositoryFragmentSupport .class )));
@@ -189,6 +230,10 @@ private QueryInteraction createStringQuery(RepositoryInformation repositoryInfor
189230 if (queryMethod .hasAnnotatedQuery () && queryAnnotation != null ) {
190231 query = new QueryInteraction (new AotStringQuery (queryMethod .getAnnotatedQuery ()), queryAnnotation .count (),
191232 queryAnnotation .delete (), queryAnnotation .exists ());
233+ } else if (namedQueries .hasQuery (queryMethod .getNamedQueryName ())) {
234+ query = new QueryInteraction (new AotStringQuery (namedQueries .getQuery (queryMethod .getNamedQueryName ())),
235+ queryAnnotation != null && queryAnnotation .count (), queryAnnotation != null && queryAnnotation .delete (),
236+ queryAnnotation != null && queryAnnotation .exists ());
192237 } else {
193238
194239 PartTree partTree = new PartTree (queryMethod .getName (), repositoryInformation .getDomainType ());
0 commit comments