diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScanner.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScanner.java index 3bd3a50aafa..1dbe3e75915 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScanner.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesScanner.java @@ -18,6 +18,7 @@ package org.springframework.orm.jpa.persistenceunit; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.annotation.Annotation; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; @@ -72,6 +73,15 @@ public final class PersistenceManagedTypesScanner { entityTypeFilters.add(new AnnotationTypeFilter(Embeddable.class, false)); entityTypeFilters.add(new AnnotationTypeFilter(MappedSuperclass.class, false)); entityTypeFilters.add(new AnnotationTypeFilter(Converter.class, false)); + try { + @SuppressWarnings("unchecked") + Class discoverable = (Class) ClassUtils.forName( + "jakarta.persistence.spi.Discoverable", PersistenceManagedTypesScanner.class.getClassLoader()); + entityTypeFilters.add(new AnnotationTypeFilter(discoverable, true)); + } + catch (ClassNotFoundException ex) { + // JPA 4.0 API not present - simply skip. + } } private final ResourcePatternResolver resourcePatternResolver; @@ -147,7 +157,7 @@ public final class PersistenceManagedTypesScanner { } } } - else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { + if (className.endsWith(PACKAGE_INFO_SUFFIX)) { scanResult.managedPackages.add(className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length())); } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java index 6141eaa62e7..557f06b54fa 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java @@ -262,16 +262,13 @@ public class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo { // Fast path for SmartPersistenceUnitInfo JTA check return (getTransactionType() == PersistenceUnitTransactionType.JTA); } - else if (method.getName().equals("getAllManagedClassNames")) { - // JPA 4.0 letting the container perform the scanning -> - // with Spring, only makes sense with typical default persistence unit. - if (excludeUnlistedClasses() && getMappingFileNames().isEmpty()) { - List mergedClassesAndPackages = new ArrayList<>(getManagedClassNames()); - mergedClassesAndPackages.addAll(getManagedPackages()); - return mergedClassesAndPackages; + else if (method.getName().equals("getAllClassNames")) { + // JPA 4.0 letting the container perform the scanning + if (excludeUnlistedClasses()) { + return getManagedClassNames(); // typically coming from Spring default persistence unit } throw new UnsupportedOperationException( - "JPA 4.0 getAllManagedClassNames only supported with exclude-unlisted-classes and no orm.xml"); + "JPA 4.0 getAllClassNames only supported with exclude-unlisted-classes"); } // Regular methods to be delegated to SpringPersistenceUnitInfo