Browse Source

Polishing

pull/35814/head
Juergen Hoeller 1 month ago
parent
commit
0243059f53
  1. 41
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java
  2. 41
      spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java

41
spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java

@ -64,14 +64,13 @@ import org.springframework.util.ReflectionUtils;
* @author Sebastien Deleuze * @author Sebastien Deleuze
* @since 6.0 * @since 6.0
*/ */
@SuppressWarnings("unchecked")
class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor { class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
private static final boolean jpaPresent = ClassUtils.isPresent("jakarta.persistence.Entity", private static final boolean jpaPresent = ClassUtils.isPresent("jakarta.persistence.Entity",
PersistenceManagedTypesBeanRegistrationAotProcessor.class.getClassLoader()); PersistenceManagedTypesBeanRegistrationAotProcessor.class.getClassLoader());
@Nullable
@Override @Override
@Nullable
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
if (jpaPresent) { if (jpaPresent) {
if (PersistenceManagedTypes.class.isAssignableFrom(registeredBean.getBeanClass())) { if (PersistenceManagedTypes.class.isAssignableFrom(registeredBean.getBeanClass())) {
@ -82,12 +81,12 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
return null; return null;
} }
private static final class JpaManagedTypesBeanRegistrationCodeFragments extends BeanRegistrationCodeFragmentsDecorator { private static final class JpaManagedTypesBeanRegistrationCodeFragments extends BeanRegistrationCodeFragmentsDecorator {
private static final List<Class<? extends Annotation>> CALLBACK_TYPES = List.of(PreUpdate.class, private static final List<Class<? extends Annotation>> CALLBACK_TYPES = List.of(PreUpdate.class,
PostUpdate.class, PrePersist.class, PostPersist.class, PreRemove.class, PostRemove.class, PostLoad.class); PostUpdate.class, PrePersist.class, PostPersist.class, PreRemove.class, PostRemove.class, PostLoad.class);
private static final ParameterizedTypeName LIST_OF_STRINGS_TYPE = ParameterizedTypeName.get(List.class, String.class); private static final ParameterizedTypeName LIST_OF_STRINGS_TYPE = ParameterizedTypeName.get(List.class, String.class);
private final RegisteredBean registeredBean; private final RegisteredBean registeredBean;
@ -102,8 +101,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
@Override @Override
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext, public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
BeanRegistrationCode beanRegistrationCode, BeanRegistrationCode beanRegistrationCode, boolean allowDirectSupplierShortcut) {
boolean allowDirectSupplierShortcut) {
PersistenceManagedTypes persistenceManagedTypes = this.registeredBean.getBeanFactory() PersistenceManagedTypes persistenceManagedTypes = this.registeredBean.getBeanFactory()
.getBean(this.registeredBean.getBeanName(), PersistenceManagedTypes.class); .getBean(this.registeredBean.getBeanName(), PersistenceManagedTypes.class);
contributeHints(generationContext.getRuntimeHints(), contributeHints(generationContext.getRuntimeHints(),
@ -140,7 +139,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
contributeHibernateHints(hints, classLoader, managedClass); contributeHibernateHints(hints, classLoader, managedClass);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Failed to instantiate the managed class: " + managedClassName, ex); throw new IllegalArgumentException("Failed to instantiate JPA managed class: " + managedClassName, ex);
} }
} }
} }
@ -149,7 +148,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
EntityListeners entityListeners = AnnotationUtils.findAnnotation(managedClass, EntityListeners.class); EntityListeners entityListeners = AnnotationUtils.findAnnotation(managedClass, EntityListeners.class);
if (entityListeners != null) { if (entityListeners != null) {
for (Class<?> entityListener : entityListeners.value()) { for (Class<?> entityListener : entityListeners.value()) {
hints.reflection().registerType(entityListener, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS); hints.reflection().registerType(entityListener,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS);
} }
} }
} }
@ -169,12 +169,14 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
} }
Convert convertClassAnnotation = AnnotationUtils.findAnnotation(managedClass, Convert.class); Convert convertClassAnnotation = AnnotationUtils.findAnnotation(managedClass, Convert.class);
if (convertClassAnnotation != null) { if (convertClassAnnotation != null) {
reflectionHints.registerType(convertClassAnnotation.converter(), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); reflectionHints.registerType(convertClassAnnotation.converter(),
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
} }
ReflectionUtils.doWithFields(managedClass, field -> { ReflectionUtils.doWithFields(managedClass, field -> {
Convert convertFieldAnnotation = AnnotationUtils.findAnnotation(field, Convert.class); Convert convertFieldAnnotation = AnnotationUtils.findAnnotation(field, Convert.class);
if (convertFieldAnnotation != null && convertFieldAnnotation.converter() != void.class) { if (convertFieldAnnotation != null && convertFieldAnnotation.converter() != void.class) {
reflectionHints.registerType(convertFieldAnnotation.converter(), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); reflectionHints.registerType(convertFieldAnnotation.converter(),
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
} }
}); });
} }
@ -186,11 +188,11 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
method -> CALLBACK_TYPES.stream().anyMatch(method::isAnnotationPresent)); method -> CALLBACK_TYPES.stream().anyMatch(method::isAnnotationPresent));
} }
@SuppressWarnings("unchecked")
private void contributeHibernateHints(RuntimeHints hints, @Nullable ClassLoader classLoader, Class<?> managedClass) { private void contributeHibernateHints(RuntimeHints hints, @Nullable ClassLoader classLoader, Class<?> managedClass) {
ReflectionHints reflection = hints.reflection(); ReflectionHints reflection = hints.reflection();
Class<? extends Annotation> embeddableInstantiatorClass = loadClass("org.hibernate.annotations.EmbeddableInstantiator", classLoader); Class<? extends Annotation> embeddableInstantiatorClass =
loadClass("org.hibernate.annotations.EmbeddableInstantiator", classLoader);
if (embeddableInstantiatorClass != null) { if (embeddableInstantiatorClass != null) {
registerForReflection(reflection, registerForReflection(reflection,
AnnotationUtils.findAnnotation(managedClass, embeddableInstantiatorClass), "value"); AnnotationUtils.findAnnotation(managedClass, embeddableInstantiatorClass), "value");
@ -204,7 +206,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, embeddableInstantiatorClass), "value")); AnnotationUtils.findAnnotation(method, embeddableInstantiatorClass), "value"));
} }
Class<? extends Annotation> valueGenerationTypeClass = loadClass("org.hibernate.annotations.ValueGenerationType", classLoader); Class<? extends Annotation> valueGenerationTypeClass =
loadClass("org.hibernate.annotations.ValueGenerationType", classLoader);
if (valueGenerationTypeClass != null) { if (valueGenerationTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection, ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, valueGenerationTypeClass), "generatedBy")); AnnotationUtils.findAnnotation(field, valueGenerationTypeClass), "generatedBy"));
@ -212,7 +215,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, valueGenerationTypeClass), "generatedBy")); AnnotationUtils.findAnnotation(method, valueGenerationTypeClass), "generatedBy"));
} }
Class<? extends Annotation> idGeneratorTypeClass = loadClass("org.hibernate.annotations.IdGeneratorType", classLoader); Class<? extends Annotation> idGeneratorTypeClass =
loadClass("org.hibernate.annotations.IdGeneratorType", classLoader);
if (idGeneratorTypeClass != null) { if (idGeneratorTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection, ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, idGeneratorTypeClass), "value")); AnnotationUtils.findAnnotation(field, idGeneratorTypeClass), "value"));
@ -220,7 +224,8 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
AnnotationUtils.findAnnotation(method, idGeneratorTypeClass), "value")); AnnotationUtils.findAnnotation(method, idGeneratorTypeClass), "value"));
} }
Class<? extends Annotation> attributeBinderTypeClass = loadClass("org.hibernate.annotations.AttributeBinderType", classLoader); Class<? extends Annotation> attributeBinderTypeClass =
loadClass("org.hibernate.annotations.AttributeBinderType", classLoader);
if (attributeBinderTypeClass != null) { if (attributeBinderTypeClass != null) {
ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection, ReflectionUtils.doWithFields(managedClass, field -> registerForReflection(reflection,
AnnotationUtils.findAnnotation(field, attributeBinderTypeClass), "binder")); AnnotationUtils.findAnnotation(field, attributeBinderTypeClass), "binder"));
@ -229,6 +234,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
} }
} }
@SuppressWarnings("unchecked")
@Nullable @Nullable
private static Class<? extends Annotation> loadClass(String className, @Nullable ClassLoader classLoader) { private static Class<? extends Annotation> loadClass(String className, @Nullable ClassLoader classLoader) {
try { try {
@ -239,13 +245,14 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
} }
} }
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Not-null assertion performed in ReflectionHints.registerType
private void registerForReflection(ReflectionHints reflection, @Nullable Annotation annotation, String attribute) { private void registerForReflection(ReflectionHints reflection, @Nullable Annotation annotation, String attribute) {
if (annotation == null) { if (annotation == null) {
return; return;
} }
Class<?> embeddableInstantiatorClass = (Class<?>) AnnotationUtils.getAnnotationAttributes(annotation).get(attribute); Class<?> type = (Class<?>) AnnotationUtils.getAnnotationAttributes(annotation).get(attribute);
reflection.registerType(embeddableInstantiatorClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); reflection.registerType(type, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
} }
} }
} }

41
spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java

@ -66,8 +66,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
GenericApplicationContext context = new AnnotationConfigApplicationContext(); GenericApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean(JpaDomainConfiguration.class); context.registerBean(JpaDomainConfiguration.class);
compile(context, (initializer, compiled) -> { compile(context, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext( GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
initializer);
PersistenceManagedTypes persistenceManagedTypes = freshApplicationContext.getBean( PersistenceManagedTypes persistenceManagedTypes = freshApplicationContext.getBean(
"persistenceManagedTypes", PersistenceManagedTypes.class); "persistenceManagedTypes", PersistenceManagedTypes.class);
assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder( assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
@ -121,6 +120,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void compile(GenericApplicationContext applicationContext, private void compile(GenericApplicationContext applicationContext,
BiConsumer<ApplicationContextInitializer<GenericApplicationContext>, Compiled> result) { BiConsumer<ApplicationContextInitializer<GenericApplicationContext>, Compiled> result) {
ApplicationContextAotGenerator generator = new ApplicationContextAotGenerator(); ApplicationContextAotGenerator generator = new ApplicationContextAotGenerator();
TestGenerationContext generationContext = new TestGenerationContext(); TestGenerationContext generationContext = new TestGenerationContext();
generator.processAheadOfTime(applicationContext, generationContext); generator.processAheadOfTime(applicationContext, generationContext);
@ -131,6 +131,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
private GenericApplicationContext toFreshApplicationContext( private GenericApplicationContext toFreshApplicationContext(
ApplicationContextInitializer<GenericApplicationContext> initializer) { ApplicationContextInitializer<GenericApplicationContext> initializer) {
GenericApplicationContext freshApplicationContext = new GenericApplicationContext(); GenericApplicationContext freshApplicationContext = new GenericApplicationContext();
initializer.initialize(freshApplicationContext); initializer.initialize(freshApplicationContext);
freshApplicationContext.refresh(); freshApplicationContext.refresh();
@ -144,21 +145,6 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
result.accept(generationContext.getRuntimeHints()); result.accept(generationContext.getRuntimeHints());
} }
public static class JpaDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
@Override
protected String packageToScan() {
return "org.springframework.orm.jpa.domain";
}
}
public static class HibernateDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
@Override
protected String packageToScan() {
return "org.springframework.orm.jpa.hibernate.domain";
}
}
public abstract static class AbstractEntityManagerWithPackagesToScanConfiguration { public abstract static class AbstractEntityManagerWithPackagesToScanConfiguration {
@ -179,13 +165,13 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
@Bean @Bean
public PersistenceManagedTypes persistenceManagedTypes(ResourceLoader resourceLoader) { public PersistenceManagedTypes persistenceManagedTypes(ResourceLoader resourceLoader) {
this.scanningInvoked = true; this.scanningInvoked = true;
return new PersistenceManagedTypesScanner(resourceLoader) return new PersistenceManagedTypesScanner(resourceLoader).scan(packageToScan());
.scan(packageToScan());
} }
@Bean @Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
JpaVendorAdapter jpaVendorAdapter, PersistenceManagedTypes persistenceManagedTypes) { JpaVendorAdapter jpaVendorAdapter, PersistenceManagedTypes persistenceManagedTypes) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource); entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
@ -194,7 +180,24 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
} }
protected abstract String packageToScan(); protected abstract String packageToScan();
}
public static class JpaDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
@Override
protected String packageToScan() {
return "org.springframework.orm.jpa.domain";
}
}
public static class HibernateDomainConfiguration extends AbstractEntityManagerWithPackagesToScanConfiguration {
@Override
protected String packageToScan() {
return "org.springframework.orm.jpa.hibernate.domain";
}
} }
} }

Loading…
Cancel
Save