Skip to content

Commit 09a1eb6

Browse files
committed
Polishing.
Run AotMetamodel against live EntityManagerFactory, use Environment to check for AOT repository enabled flag. See #3830
1 parent f9cdca1 commit 09a1eb6

File tree

9 files changed

+60
-447
lines changed

9 files changed

+60
-447
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/AotMetamodel.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public EntityManager entityManager() {
9696
return entityManager.get();
9797
}
9898

99-
// TODO: Capture an existing factory bean (e.g. EntityManagerFactoryInfo) to extract PersistenceInfo
10099
public EntityManagerFactory getEntityManagerFactory() {
101100
return entityManagerFactory.get();
102101
}
@@ -125,7 +124,8 @@ public void addTransformer(ClassTransformer classTransformer) {
125124
public List<String> getManagedClassNames() {
126125
return persistenceUnitInfo.getManagedClassNames();
127126
}
128-
}, Map.of("hibernate.dialect", "org.hibernate.dialect.H2Dialect")).build();
127+
}, Map.of("hibernate.dialect", "org.hibernate.dialect.H2Dialect", "hibernate.boot.allow_jdbc_metadata_access",
128+
"false")).build();
129129
}
130130

131131
}

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/JpaCodeBlocks.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.springframework.javapoet.CodeBlock;
4646
import org.springframework.javapoet.CodeBlock.Builder;
4747
import org.springframework.javapoet.TypeName;
48+
import org.springframework.util.Assert;
4849
import org.springframework.util.ClassUtils;
4950
import org.springframework.util.ObjectUtils;
5051
import org.springframework.util.StringUtils;
@@ -140,6 +141,8 @@ public QueryBlockBuilder queryRewriter(@Nullable Class<?> queryRewriter) {
140141
*/
141142
public CodeBlock build() {
142143

144+
Assert.notNull(queries, "Queries must not be null");
145+
143146
boolean isProjecting = context.getReturnedType().isProjecting();
144147
Class<?> actualReturnType = isProjecting ? context.getActualReturnType().toClass()
145148
: context.getRepositoryInformation().getDomainType();
@@ -153,7 +156,6 @@ public CodeBlock build() {
153156
builder.add("\n");
154157

155158
String queryStringVariableName = null;
156-
157159
String queryRewriterName = null;
158160

159161
if (queries.result() instanceof StringAotQuery && queryRewriter != QueryRewriter.IdentityQueryRewriter.class) {
@@ -162,7 +164,7 @@ public CodeBlock build() {
162164
builder.addStatement("$T $L = new $T()", queryRewriter, queryRewriterName, queryRewriter);
163165
}
164166

165-
if (queries != null && queries.result() instanceof StringAotQuery sq) {
167+
if (queries.result() instanceof StringAotQuery sq) {
166168

167169
queryStringVariableName = "%sString".formatted(queryVariableName);
168170
builder.add(buildQueryString(sq, queryStringVariableName));
@@ -183,7 +185,8 @@ public CodeBlock build() {
183185
}
184186

185187
if ((StringUtils.hasText(sortParameterName) || StringUtils.hasText(dynamicReturnType))
186-
&& queries.result() instanceof StringAotQuery) {
188+
&& queries != null && queries.result() instanceof StringAotQuery
189+
&& StringUtils.hasText(queryStringVariableName)) {
187190
builder.add(applyRewrite(sortParameterName, dynamicReturnType, queryStringVariableName, actualReturnType));
188191
}
189192

@@ -605,7 +608,7 @@ public CodeBlock build() {
605608
}
606609
} else if (aotQuery != null && aotQuery.isExists()) {
607610
builder.addStatement("return !$L.getResultList().isEmpty()", queryVariableName);
608-
} else {
611+
} else if (aotQuery != null) {
609612

610613
if (context.getReturnedType().isProjecting()) {
611614

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/JpaRepositoryContributor.java

-2
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,6 @@ protected void customizeConstructor(AotRepositoryConstructorBuilder constructorB
189189
MergedAnnotation<EntityGraph> entityGraph = context.getAnnotation(EntityGraph.class);
190190
MergedAnnotation<Modifying> modifying = context.getAnnotation(Modifying.class);
191191

192-
body.add(context.codeBlocks().logDebug("invoking [%s]".formatted(context.getMethod().getName())));
193-
194192
AotEntityGraph aotEntityGraph = entityGraphLookup.findEntityGraph(entityGraph, repositoryInformation,
195193
returnedType, queryMethod);
196194

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.springframework.data.jpa.repository.config.BeanDefinitionNames.*;
1919

2020
import jakarta.persistence.Entity;
21+
import jakarta.persistence.EntityManagerFactory;
2122
import jakarta.persistence.MappedSuperclass;
2223
import jakarta.persistence.PersistenceContext;
2324
import jakarta.persistence.PersistenceUnit;
@@ -38,6 +39,7 @@
3839
import org.springframework.aot.generate.GenerationContext;
3940
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
4041
import org.springframework.beans.factory.config.BeanDefinition;
42+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
4143
import org.springframework.beans.factory.support.AbstractBeanDefinition;
4244
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
4345
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -325,22 +327,29 @@ static boolean isActive(@Nullable ClassLoader classLoader) {
325327
*/
326328
public static class JpaRepositoryRegistrationAotProcessor extends RepositoryRegistrationAotProcessor {
327329

328-
protected RepositoryContributor contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {
330+
protected @Nullable RepositoryContributor contribute(AotRepositoryContext repositoryContext,
331+
GenerationContext generationContext) {
329332

330-
// don't register domain types nor annotations.
331-
332-
if (!AotContext.aotGeneratedRepositoriesEnabled()) {
333+
boolean enabled = Boolean.parseBoolean(
334+
repositoryContext.getEnvironment().getProperty(AotContext.GENERATED_REPOSITORIES_ENABLED, "false"));
335+
if (!enabled) {
333336
return null;
334337
}
335338

336-
return new JpaRepositoryContributor(repositoryContext);
339+
ConfigurableListableBeanFactory beanFactory = repositoryContext.getBeanFactory();
340+
EntityManagerFactory emf = beanFactory.getBeanProvider(EntityManagerFactory.class).getIfAvailable();
341+
342+
return emf != null ? new JpaRepositoryContributor(repositoryContext, emf)
343+
: new JpaRepositoryContributor(repositoryContext);
337344
}
338345

339346
@Nullable
340347
@Override
348+
@SuppressWarnings("NullAway")
341349
protected RepositoryConfiguration<?> getRepositoryMetadata(RegisteredBean bean) {
342350
RepositoryConfiguration<?> configuration = super.getRepositoryMetadata(bean);
343-
if (!configuration.getRepositoryBaseClassName().isEmpty()) {
351+
352+
if (configuration != null && configuration.getRepositoryBaseClassName().isPresent()) {
344353
return configuration;
345354
}
346355
return new Meh<>(configuration);

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/NamedQuery.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.data.repository.query.ResultProcessor;
3535
import org.springframework.data.repository.query.ReturnedType;
3636
import org.springframework.data.util.Lazy;
37+
import org.springframework.util.StringUtils;
3738

3839
/**
3940
* Implementation of {@link RepositoryQuery} based on {@link jakarta.persistence.NamedQuery}s.
@@ -97,12 +98,26 @@ private NamedQuery(JpaQueryMethod method, EntityManager em, JpaQueryConfiguratio
9798

9899
String queryString = extractor.extractQueryString(namedQuery);
99100

100-
// TODO: What is queryString is null?
101101
DeclaredQuery declaredQuery;
102-
if (method.isNativeQuery() || (namedQuery != null && namedQuery.toString().contains("NativeQuery"))) {
103-
declaredQuery = DeclaredQuery.nativeQuery(queryString);
104-
} else {
105-
declaredQuery = DeclaredQuery.jpqlQuery(queryString);
102+
if (StringUtils.hasText(queryString)) {
103+
if (method.isNativeQuery() || namedQuery.toString().contains("NativeQuery")) {
104+
declaredQuery = DeclaredQuery.nativeQuery(queryString);
105+
} else {
106+
declaredQuery = DeclaredQuery.jpqlQuery(queryString);
107+
}
108+
}
109+
else {
110+
declaredQuery = new DeclaredQuery() {
111+
@Override
112+
public boolean isNative() {
113+
return false;
114+
}
115+
116+
@Override
117+
public String getQueryString() {
118+
return "";
119+
}
120+
};
106121
}
107122

108123
this.entityQuery = Lazy.of(() -> EntityQuery.create(declaredQuery, queryConfiguration.getSelector()));

0 commit comments

Comments
 (0)