1717
1818import jakarta .persistence .EntityManager ;
1919import jakarta .persistence .EntityManagerFactory ;
20+ import jakarta .persistence .PersistenceUnitUtil ;
2021import jakarta .persistence .metamodel .Metamodel ;
2122import jakarta .persistence .spi .PersistenceUnitInfo ;
2223
2324import java .lang .reflect .Method ;
2425import java .util .Map ;
2526import java .util .Optional ;
27+ import java .util .function .Function ;
2628
2729import org .jspecify .annotations .Nullable ;
2830
3234import org .springframework .core .annotation .MergedAnnotation ;
3335import org .springframework .core .annotation .MergedAnnotations ;
3436import org .springframework .data .jpa .provider .PersistenceProvider ;
37+ import org .springframework .data .jpa .provider .QueryExtractor ;
3538import org .springframework .data .jpa .repository .EntityGraph ;
3639import org .springframework .data .jpa .repository .Modifying ;
3740import org .springframework .data .jpa .repository .NativeQuery ;
3841import org .springframework .data .jpa .repository .Query ;
3942import org .springframework .data .jpa .repository .QueryHints ;
43+ import org .springframework .data .jpa .repository .query .JpaEntityMetadata ;
4044import org .springframework .data .jpa .repository .query .JpaParameters ;
4145import org .springframework .data .jpa .repository .query .JpaQueryMethod ;
4246import org .springframework .data .jpa .repository .query .Procedure ;
4347import org .springframework .data .jpa .repository .query .QueryEnhancerSelector ;
48+ import org .springframework .data .jpa .repository .support .JpaEntityInformationSupport ;
49+ import org .springframework .data .projection .ProjectionFactory ;
4450import org .springframework .data .repository .aot .generate .AotRepositoryClassBuilder ;
4551import org .springframework .data .repository .aot .generate .AotRepositoryConstructorBuilder ;
4652import org .springframework .data .repository .aot .generate .MethodContributor ;
4753import org .springframework .data .repository .aot .generate .QueryMetadata ;
4854import org .springframework .data .repository .aot .generate .RepositoryContributor ;
4955import org .springframework .data .repository .config .AotRepositoryContext ;
56+ import org .springframework .data .repository .core .RepositoryMetadata ;
5057import org .springframework .data .repository .core .support .RepositoryFactoryBeanSupport ;
58+ import org .springframework .data .repository .query .ParametersSource ;
5159import org .springframework .data .repository .query .QueryMethod ;
5260import org .springframework .data .repository .query .ReturnedType ;
5361import org .springframework .data .util .TypeInformation ;
7078public class JpaRepositoryContributor extends RepositoryContributor {
7179
7280private final Metamodel metamodel ;
81+ private final PersistenceUnitUtil persistenceUnitUtil ;
7382private final PersistenceProvider persistenceProvider ;
7483private final QueriesFactory queriesFactory ;
7584private final EntityGraphLookup entityGraphLookup ;
@@ -88,28 +97,24 @@ public JpaRepositoryContributor(AotRepositoryContext repositoryContext, Persiste
8897}
8998
9099public JpaRepositoryContributor (AotRepositoryContext repositoryContext , EntityManagerFactory entityManagerFactory ) {
91- this (repositoryContext , entityManagerFactory .getMetamodel (),
92- PersistenceProvider .fromEntityManagerFactory (entityManagerFactory ),
93- new QueriesFactory (repositoryContext .getConfigurationSource (), entityManagerFactory ,
94- repositoryContext .getRequiredClassLoader ()),
95- new EntityGraphLookup (entityManagerFactory ));
100+ this (repositoryContext , entityManagerFactory , entityManagerFactory .getMetamodel ());
96101}
97102
98103private JpaRepositoryContributor (AotRepositoryContext repositoryContext , AotMetamodel metamodel ) {
99- this (repositoryContext , metamodel ,
100- PersistenceProvider .fromEntityManagerFactory (metamodel .getEntityManagerFactory ()),
101- new QueriesFactory (repositoryContext .getConfigurationSource (), metamodel .getEntityManagerFactory (),
102- repositoryContext .getRequiredClassLoader ()),
103- new EntityGraphLookup (metamodel .getEntityManagerFactory ()));
104+ this (repositoryContext , metamodel .getEntityManagerFactory (), metamodel );
104105}
105106
106- private JpaRepositoryContributor (AotRepositoryContext repositoryContext , Metamodel metamodel ,
107- PersistenceProvider persistenceProvider , QueriesFactory queriesFactory , EntityGraphLookup entityGraphLookup ) {
107+ private JpaRepositoryContributor (AotRepositoryContext repositoryContext , EntityManagerFactory entityManagerFactory ,
108+ Metamodel metamodel ) {
109+
108110super (repositoryContext );
111+
109112this .metamodel = metamodel ;
110- this .persistenceProvider = persistenceProvider ;
111- this .queriesFactory = queriesFactory ;
112- this .entityGraphLookup = entityGraphLookup ;
113+ this .persistenceUnitUtil = entityManagerFactory .getPersistenceUnitUtil ();
114+ this .persistenceProvider = PersistenceProvider .fromEntityManagerFactory (entityManagerFactory );
115+ this .queriesFactory = new QueriesFactory (repositoryContext .getConfigurationSource (), entityManagerFactory ,
116+ repositoryContext .getRequiredClassLoader ());
117+ this .entityGraphLookup = new EntityGraphLookup (entityManagerFactory );
113118this .context = repositoryContext ;
114119}
115120
@@ -159,8 +164,10 @@ private Optional<Class<QueryEnhancerSelector>> getQueryEnhancerSelectorClass() {
159164@ Override
160165protected @ Nullable MethodContributor <? extends QueryMethod > contributeQueryMethod (Method method ) {
161166
162- JpaQueryMethod queryMethod = new JpaQueryMethod (method , getRepositoryInformation (), getProjectionFactory (),
163- persistenceProvider );
167+ JpaEntityMetadata <?> entityInformation = JpaEntityInformationSupport
168+ .getEntityInformation (getRepositoryInformation ().getDomainType (), metamodel , persistenceUnitUtil );
169+ AotJpaQueryMethod queryMethod = new AotJpaQueryMethod (method , getRepositoryInformation (), entityInformation ,
170+ getProjectionFactory (), persistenceProvider , JpaParameters ::new );
164171
165172Optional <Class <QueryEnhancerSelector >> queryEnhancerSelectorClass = getQueryEnhancerSelectorClass ();
166173QueryEnhancerSelector selector = queryEnhancerSelectorClass .map (BeanUtils ::instantiateClass )
@@ -271,4 +278,27 @@ public Map<String, Object> serialize() {
271278}
272279}
273280
281+ /**
282+ * AOT extension to {@link JpaQueryMethod} providing a metamodel backed {@link JpaEntityMetadata} object.
283+ */
284+ static class AotJpaQueryMethod extends JpaQueryMethod {
285+
286+ private final JpaEntityMetadata <?> entityMetadata ;
287+
288+ public AotJpaQueryMethod (Method method , RepositoryMetadata metadata , JpaEntityMetadata <?> entityMetadata ,
289+ ProjectionFactory factory , QueryExtractor extractor ,
290+ Function <ParametersSource , JpaParameters > parametersFunction ) {
291+
292+ super (method , metadata , factory , extractor , parametersFunction );
293+
294+ this .entityMetadata = entityMetadata ;
295+ }
296+
297+ @ Override
298+ public JpaEntityMetadata <?> getEntityInformation () {
299+ return this .entityMetadata ;
300+ }
301+
302+ }
303+
274304}
0 commit comments