Browse Source

Add hints for entities package-private methods

Closes gh-35711
pull/35814/head
Sébastien Deleuze 1 month ago
parent
commit
5aec239261
  1. 13
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java
  2. 50
      spring-orm/src/test/java/org/springframework/orm/jpa/domain/Car.java
  3. 11
      spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java
  4. 4
      spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScannerTests.java

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

@ -137,6 +137,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessor implements BeanRegistr
contributeConverterHints(hints, managedClass); contributeConverterHints(hints, managedClass);
contributeCallbackHints(hints, managedClass); contributeCallbackHints(hints, managedClass);
contributeHibernateHints(hints, classLoader, managedClass); contributeHibernateHints(hints, classLoader, managedClass);
contributePackagePrivateHints(hints, managedClass);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Failed to instantiate JPA managed class: " + managedClassName, 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") @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) {

50
spring-orm/src/test/java/org/springframework/orm/jpa/domain/Car.java

@ -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;
}
}

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

@ -38,6 +38,7 @@ import org.springframework.core.test.tools.Compiled;
import org.springframework.core.test.tools.TestCompiler; import org.springframework.core.test.tools.TestCompiler;
import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 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.DriversLicense;
import org.springframework.orm.jpa.domain.Employee; import org.springframework.orm.jpa.domain.Employee;
import org.springframework.orm.jpa.domain.EmployeeCategoryConverter; import org.springframework.orm.jpa.domain.EmployeeCategoryConverter;
@ -71,7 +72,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
"persistenceManagedTypes", PersistenceManagedTypes.class); "persistenceManagedTypes", PersistenceManagedTypes.class);
assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder( assertThat(persistenceManagedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
DriversLicense.class.getName(), Person.class.getName(), Employee.class.getName(), DriversLicense.class.getName(), Person.class.getName(), Employee.class.getName(),
EmployeeLocationConverter.class.getName()); EmployeeLocationConverter.class.getName(), Car.class.getName());
assertThat(persistenceManagedTypes.getManagedPackages()).isEmpty(); assertThat(persistenceManagedTypes.getManagedPackages()).isEmpty();
assertThat(freshApplicationContext.getBean( assertThat(freshApplicationContext.getBean(
JpaDomainConfiguration.class).scanningInvoked).isFalse(); JpaDomainConfiguration.class).scanningInvoked).isFalse();
@ -104,6 +105,14 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints); .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints);
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeLocation.class) assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeLocation.class)
.withMemberCategories(MemberCategory.DECLARED_FIELDS)).accepts(hints); .withMemberCategories(MemberCategory.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);
}); });
} }

4
spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScannerTests.java

@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.testfixture.index.CandidateComponentsTestClassLoader; import org.springframework.context.testfixture.index.CandidateComponentsTestClassLoader;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader; 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.DriversLicense;
import org.springframework.orm.jpa.domain.Employee; import org.springframework.orm.jpa.domain.Employee;
import org.springframework.orm.jpa.domain.EmployeeLocationConverter; import org.springframework.orm.jpa.domain.EmployeeLocationConverter;
@ -52,7 +53,7 @@ class PersistenceManagedTypesScannerTests {
PersistenceManagedTypes managedTypes = this.scanner.scan("org.springframework.orm.jpa.domain"); PersistenceManagedTypes managedTypes = this.scanner.scan("org.springframework.orm.jpa.domain");
assertThat(managedTypes.getManagedClassNames()).containsExactlyInAnyOrder( assertThat(managedTypes.getManagedClassNames()).containsExactlyInAnyOrder(
Person.class.getName(), DriversLicense.class.getName(), Employee.class.getName(), Person.class.getName(), DriversLicense.class.getName(), Employee.class.getName(),
EmployeeLocationConverter.class.getName()); EmployeeLocationConverter.class.getName(), Car.class.getName());
assertThat(managedTypes.getManagedPackages()).isEmpty(); assertThat(managedTypes.getManagedPackages()).isEmpty();
} }
@ -66,6 +67,7 @@ class PersistenceManagedTypesScannerTests {
verify(filter).matches(DriversLicense.class.getName()); verify(filter).matches(DriversLicense.class.getName());
verify(filter).matches(Employee.class.getName()); verify(filter).matches(Employee.class.getName());
verify(filter).matches(EmployeeLocationConverter.class.getName()); verify(filter).matches(EmployeeLocationConverter.class.getName());
verify(filter).matches(Car.class.getName());
verifyNoMoreInteractions(filter); verifyNoMoreInteractions(filter);
} }

Loading…
Cancel
Save