diff --git a/pom.xml b/pom.xml
index 6a62754327..997e4d7b27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-jpa-parent
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
pom
Spring Data JPA Parent
@@ -35,7 +35,7 @@
4.3
8.0.23
42.2.19
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2593-SNAPSHOT
0.10.3
org.hibernate
diff --git a/spring-data-envers/pom.xml b/spring-data-envers/pom.xml
index 59eb8eab88..bc433c72e5 100755
--- a/spring-data-envers/pom.xml
+++ b/spring-data-envers/pom.xml
@@ -5,12 +5,12 @@
org.springframework.data
spring-data-envers
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
org.springframework.data
spring-data-jpa-parent
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
../pom.xml
diff --git a/spring-data-jpa-distribution/pom.xml b/spring-data-jpa-distribution/pom.xml
index bba8571672..544fdb07bf 100644
--- a/spring-data-jpa-distribution/pom.xml
+++ b/spring-data-jpa-distribution/pom.xml
@@ -14,7 +14,7 @@
org.springframework.data
spring-data-jpa-parent
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
../pom.xml
diff --git a/spring-data-jpa/pom.xml b/spring-data-jpa/pom.xml
index ba9220cc2a..b2b8e464e6 100644
--- a/spring-data-jpa/pom.xml
+++ b/spring-data-jpa/pom.xml
@@ -6,7 +6,7 @@
org.springframework.data
spring-data-jpa
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
Spring Data JPA
Spring Data module for JPA repositories.
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-jpa-parent
- 3.0.0-SNAPSHOT
+ 3.0.0-GH-2497-SNAPSHOT
../pom.xml
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/DataJpaRuntimeHints.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/DataJpaRuntimeHints.java
new file mode 100644
index 0000000000..c76fd74be7
--- /dev/null
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/DataJpaRuntimeHints.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.jpa.aot;
+
+import java.util.Arrays;
+
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.RuntimeHintsRegistrar;
+import org.springframework.aot.hint.TypeReference;
+import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect;
+import org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
+import org.springframework.lang.Nullable;
+
+/**
+ * @author Christoph Strobl
+ * @since 3.0
+ */
+public class DataJpaRuntimeHints implements RuntimeHintsRegistrar {
+
+ @Override
+ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
+
+ hints.proxies().registerJdkProxy(org.springframework.data.jpa.repository.support.CrudMethodMetadata.class,
+ org.springframework.aop.SpringProxy.class, org.springframework.aop.framework.Advised.class,
+ org.springframework.core.DecoratingProxy.class);
+ hints.reflection().registerTypes(
+ Arrays.asList(TypeReference.of(AnnotationBeanConfigurerAspect.class),
+ TypeReference.of(AuditingBeanFactoryPostProcessor.class), TypeReference.of(AuditingEntityListener.class)),
+ hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS));
+ hints.reflection().registerTypes(Arrays.asList(TypeReference.of(SimpleJpaRepository.class)),
+ hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS));
+ }
+}
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
index fc0404169f..1f7cb5add5 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaAuditingRegistrar.java
@@ -21,10 +21,12 @@
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
@@ -34,7 +36,9 @@
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.repository.config.PersistentEntitiesFactoryBean;
+import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -42,6 +46,7 @@
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableJpaAuditing} annotation.
*
* @author Thomas Darimont
+ * @author Christoph Strobl
*/
class JpaAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
@@ -57,16 +62,6 @@ protected String getAuditingHandlerBeanName() {
return "jpaAuditingHandler";
}
- @Override
- protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
-
- BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
- definition.addConstructorArgReference(JPA_MAPPING_CONTEXT_BEAN_NAME);
-
- BeanDefinitionBuilder builder = super.getAuditHandlerBeanDefinitionBuilder(configuration);
- return builder.addConstructorArgValue(definition.getBeanDefinition());
- }
-
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
@@ -95,6 +90,42 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
registerInfrastructureBeanWithId(builder.getRawBeanDefinition(), AuditingEntityListener.class.getName(), registry);
}
+ @Override
+ protected void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration,
+ BeanDefinitionRegistry registry) {
+
+ String persistentEntitiesBeanName = detectPersistentEntitiesBeanName(registry);
+
+ if (persistentEntitiesBeanName == null) {
+
+ persistentEntitiesBeanName = BeanDefinitionReaderUtils.uniqueBeanName("jpaPersistentEntities", registry);
+
+ // TODO: https://github.com/spring-projects/spring-framework/issues/28728
+ BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntities.class) //
+ .setFactoryMethod("of") //
+ .addConstructorArgReference(JPA_MAPPING_CONTEXT_BEAN_NAME);
+
+ registry.registerBeanDefinition(persistentEntitiesBeanName, definition.getBeanDefinition());
+ }
+
+ builder.addConstructorArgReference(persistentEntitiesBeanName);
+ }
+
+ @Nullable
+ private static String detectPersistentEntitiesBeanName(BeanDefinitionRegistry registry) {
+
+ if (registry instanceof ListableBeanFactory beanFactory) {
+ for (String bn : beanFactory.getBeanNamesForType(PersistentEntities.class)) {
+ if (bn.startsWith("jpa")) {
+ return bn;
+ }
+ }
+ }
+
+ return null;
+ }
+
+
/**
* @param registry, the {@link BeanDefinitionRegistry} to be used to register the
* {@link AnnotationBeanConfigurerAspect}.
diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java
index 701548d565..07550f533c 100644
--- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java
+++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java
@@ -17,22 +17,26 @@
import static org.springframework.data.jpa.repository.config.BeanDefinitionNames.*;
+import jakarta.persistence.Entity;
+import jakarta.persistence.MappedSuperclass;
+import jakarta.persistence.PersistenceContext;
+import jakarta.persistence.PersistenceUnit;
+
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Locale;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import jakarta.persistence.Entity;
-import jakarta.persistence.MappedSuperclass;
-import jakarta.persistence.PersistenceContext;
-import jakarta.persistence.PersistenceUnit;
-
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigUtils;
@@ -77,6 +81,8 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi
private static final String JPA_METAMODEL_CACHE_CLEANUP_CLASSNAME = "org.springframework.data.jpa.util.JpaMetamodelCacheCleanup";
private static final String ESCAPE_CHARACTER_PROPERTY = "escapeCharacter";
+ private final Map