Merge branch '6.2.x'

This commit is contained in:
Sébastien Deleuze
2025-11-11 13:54:35 +01:00
4 changed files with 76 additions and 2 deletions
@@ -137,6 +137,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
contributeConverterHints(hints, managedClass);
contributeCallbackHints(hints, managedClass);
contributeHibernateHints(hints, classLoader, managedClass);
contributePackagePrivateHints(hints, managedClass);
}
catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Failed to instantiate JPA managed class: " + managedClassName, ex);
@@ -234,6 +235,18 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
}
}
private void contributePackagePrivateHints(RuntimeHints hints, Class<?> managedClass) {
ReflectionHints reflection = hints.reflection();
ReflectionUtils.doWithMethods(managedClass, method ->
reflection.registerMethod(method, ExecutableMode.INVOKE),
method -> {
int modifiers = method.getModifiers();
return !(java.lang.reflect.Modifier.isProtected(modifiers) ||
java.lang.reflect.Modifier.isPrivate(modifiers) ||
java.lang.reflect.Modifier.isPublic(modifiers));
});
}
@SuppressWarnings("unchecked")
private static @Nullable Class<? extends Annotation> loadClass(String className, @Nullable ClassLoader classLoader) {
try {
@@ -0,0 +1,50 @@
/*
* Copyright 2002-present 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.orm.jpa.domain;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column
private String model;
Integer getId() {
return id;
}
void setId(Integer id) {
this.id = id;
}
void setModel(String model) {
this.model = model;
}
String getModel() {
return model;
}
}
@@ -38,6 +38,7 @@ import org.springframework.core.test.tools.Compiled;
import org.springframework.core.test.tools.TestCompiler;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.domain.Car;
import org.springframework.orm.jpa.domain.DriversLicense;
import org.springframework.orm.jpa.domain.Employee;
import org.springframework.orm.jpa.domain.EmployeeCategoryConverter;
@@ -71,7 +72,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
"persistenceManagedTypes", PersistenceManagedTypes.class);
assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
DriversLicense.class.getName(), Person.class.getName(), Employee.class.getName(),
EmployeeLocationConverter.class.getName());
EmployeeLocationConverter.class.getName(), Car.class.getName());
assertThat(persistenceManagedTypes.getManagedPackages()).isEmpty();
assertThat(freshApplicationContext.getBean(
JpaDomainConfiguration.class).scanningInvoked).isFalse();
@@ -104,6 +105,14 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeLocation.class)
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onMethod(Car.class, "setId")
.invoke()).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onMethod(Car.class, "getId")
.invoke()).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onMethod(Car.class, "setModel")
.invoke()).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onMethod(Car.class, "getModel")
.invoke()).accepts(hints);
});
}
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.testfixture.index.CandidateComponentsTestClassLoader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.orm.jpa.domain.Car;
import org.springframework.orm.jpa.domain.DriversLicense;
import org.springframework.orm.jpa.domain.Employee;
import org.springframework.orm.jpa.domain.EmployeeLocationConverter;
@@ -52,7 +53,7 @@ class PersistenceManagedTypesScannerTests {
PersistenceManagedTypes managedTypes = this.scanner.scan("org.springframework.orm.jpa.domain");
assertThat(managedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
Person.class.getName(), DriversLicense.class.getName(), Employee.class.getName(),
EmployeeLocationConverter.class.getName());
EmployeeLocationConverter.class.getName(), Car.class.getName());
assertThat(managedTypes.getManagedPackages()).isEmpty();
}
@@ -66,6 +67,7 @@ class PersistenceManagedTypesScannerTests {
verify(filter).matches(DriversLicense.class.getName());
verify(filter).matches(Employee.class.getName());
verify(filter).matches(EmployeeLocationConverter.class.getName());
verify(filter).matches(Car.class.getName());
verifyNoMoreInteractions(filter);
}