diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java b/hibernate-core/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java index 3187a3721f..8a1b3bcffa 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/HibernatePersistenceProvider.java @@ -6,6 +6,10 @@ */ package org.hibernate.jpa; +import static org.hibernate.internal.HEMLogging.messageLogger; + +import java.net.URL; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -18,6 +22,7 @@ import jakarta.persistence.spi.ProviderUtil; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.internal.EntityManagerMessageLogger; import org.hibernate.jpa.boot.spi.PersistenceConfigurationDescriptor; import org.hibernate.jpa.boot.spi.PersistenceXmlParser; import org.hibernate.jpa.boot.spi.Bootstrap; @@ -26,8 +31,6 @@ import org.hibernate.jpa.boot.spi.ProviderChecker; import org.hibernate.jpa.internal.util.PersistenceUtilHelper; -import org.jboss.logging.Logger; - /** * The best-ever implementation of a JPA {@link PersistenceProvider}. * @@ -36,7 +39,7 @@ * @author Brett Meyer */ public class HibernatePersistenceProvider implements PersistenceProvider { - private static final Logger log = Logger.getLogger( HibernatePersistenceProvider.class ); + private static final EntityManagerMessageLogger log = messageLogger( HibernatePersistenceProvider.class ); private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache(); @@ -75,15 +78,7 @@ private EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String log.tracef( "Attempting to obtain correct EntityManagerFactoryBuilder for persistenceUnitName : %s", persistenceUnitName ); final Map integration = wrap( properties ); - final List units; - try { - units = PersistenceXmlParser.create( integration, providedClassLoader, providedClassLoaderService ) - .locatePersistenceUnits(); - } - catch (Exception e) { - log.debug( "Unable to locate persistence units", e ); - throw new PersistenceException( "Unable to locate persistence units", e ); - } + final Collection units = locatePersistenceUnits( integration, providedClassLoader, providedClassLoaderService ); log.debugf( "Located and parsed %s persistence units; checking each", units.size() ); @@ -130,6 +125,28 @@ protected static Map wrap(Map properties) { return properties == null ? Collections.emptyMap() : Collections.unmodifiableMap( properties ); } + // Check before changing: may be overridden in Quarkus + protected Collection locatePersistenceUnits(Map integration, ClassLoader providedClassLoader, + ClassLoaderService providedClassLoaderService) { + final Collection units; + try { + var parser = PersistenceXmlParser.create( integration, providedClassLoader, providedClassLoaderService ); + final List xmlUrls = parser.getClassLoaderService().locateResources( "META-INF/persistence.xml" ); + if ( xmlUrls.isEmpty() ) { + log.unableToFindPersistenceXmlInClasspath(); + units = List.of(); + } + else { + units = parser.parse( xmlUrls ).values(); + } + } + catch (Exception e) { + log.debug( "Unable to locate persistence units", e ); + throw new PersistenceException( "Unable to locate persistence units", e ); + } + return units; + } + /** * {@inheritDoc} *

diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/Bootstrap.java b/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/Bootstrap.java index 7fb3d21b32..4c7105c030 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/Bootstrap.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/Bootstrap.java @@ -7,6 +7,7 @@ package org.hibernate.jpa.boot.spi; import java.net.URL; +import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -66,7 +67,7 @@ public static EntityManagerFactoryBuilder getEntityManagerFactoryBuilder( PersistenceUnitTransactionType transactionType, Map integration) { return new EntityManagerFactoryBuilderImpl( - PersistenceXmlParser.create( integration ).parse( persistenceXmlUrl, transactionType ).get( persistenceUnitName ), + PersistenceXmlParser.create( integration ).parse( List.of( persistenceXmlUrl ), transactionType ).get( persistenceUnitName ), integration ); } diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java b/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java index 36ed1165dc..405701ea65 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceXmlParser.java @@ -118,53 +118,35 @@ public ClassLoaderService getClassLoaderService() { } /** - * Find all persistence-units from all accessible {@code META-INF/persistence.xml} resources - * - * @return List of descriptors for all discovered persistence-units. - */ - @SuppressWarnings("removal") - public List locatePersistenceUnits() { - Map persistenceUnits = new HashMap<>(); - final List xmlUrls = classLoaderService.locateResources( "META-INF/persistence.xml" ); - if ( xmlUrls.isEmpty() ) { - LOG.unableToFindPersistenceXmlInClasspath(); - } - else { - parsePersistenceXml( persistenceUnits, xmlUrls, PersistenceUnitTransactionType.RESOURCE_LOCAL ); - } - return new ArrayList<>( persistenceUnits.values() ); - } - - /** - * Generic method to parse a specified {@code persistence.xml} and return a Map of descriptors + * Generic method to parse specified {@code persistence.xml} files and return a Map of descriptors * for all discovered persistence-units keyed by the PU name. * - * @param persistenceXmlUrl The URL of the {@code persistence.xml} to parse + * @param persistenceXmlUrls The URL of the {@code persistence.xml} files to parse * * @return Map of persistence-unit descriptors keyed by the PU name */ @SuppressWarnings("removal") - public Map parse(URL persistenceXmlUrl) { + public Map parse(List persistenceXmlUrls) { Map persistenceUnits = new HashMap<>(); - parsePersistenceXml( persistenceUnits, persistenceXmlUrl, PersistenceUnitTransactionType.RESOURCE_LOCAL ); + parsePersistenceXml( persistenceUnits, persistenceXmlUrls, PersistenceUnitTransactionType.RESOURCE_LOCAL ); return persistenceUnits; } /** - * Generic method to parse a specified {@code persistence.xml} and return a Map of descriptors + * Generic method to parse specified {@code persistence.xml} files and return a Map of descriptors * for all discovered persistence-units keyed by the PU name. * - * @param persistenceXmlUrl The URL of the {@code persistence.xml} to parse + * @param persistenceXmlUrls The URLs of the {@code persistence.xml} files to parse * @param transactionType The specific PersistenceUnitTransactionType to incorporate into the persistence-unit descriptor * * @return Map of persistence-unit descriptors keyed by the PU name */ public Map parse( - URL persistenceXmlUrl, + List persistenceXmlUrls, @SuppressWarnings("removal") PersistenceUnitTransactionType transactionType) { Map persistenceUnits = new HashMap<>(); - parsePersistenceXml( persistenceUnits, persistenceXmlUrl, transactionType ); + parsePersistenceXml( persistenceUnits, persistenceXmlUrls, transactionType ); return persistenceUnits; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/PersistenceUnitNameTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/PersistenceUnitNameTests.java index b3d9a721f7..56d9bb017c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/PersistenceUnitNameTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/compliance/PersistenceUnitNameTests.java @@ -8,6 +8,7 @@ import java.net.URL; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.hibernate.boot.archive.scan.internal.DisabledScanner; @@ -52,7 +53,7 @@ void testSecondUnit(ServiceRegistryScope scope) { private static EntityManagerFactory loadFactory(String name, ServiceRegistryScope scope) { final URL puFile = PersistenceUnitNameTests.class.getClassLoader().getResource( "xml/jakarta/simple/2units.xml" ); - var descriptors = PersistenceXmlParser.create().parse( puFile ); + var descriptors = PersistenceXmlParser.create().parse( List.of( puFile ) ); assertThat( descriptors ).containsKey( name ); final PersistenceUnitDescriptor descriptor = descriptors.get( name ); final EntityManagerFactoryBuilder emfBuilder = Bootstrap.getEntityManagerFactoryBuilder( diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaXmlSmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaXmlSmokeTests.java index f14e48a516..702c421bd3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaXmlSmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/jakarta/JakartaXmlSmokeTests.java @@ -70,9 +70,8 @@ public void testLoadingOrmXml(ServiceRegistryScope scope) { @Test public void testLoadingPersistenceXml(ServiceRegistryScope scope) { final ClassLoaderService cls = scope.getRegistry().getService( ClassLoaderService.class ); - final URL url = cls.locateResource( "xml/jakarta/simple/persistence.xml" ); final Map descriptors = PersistenceXmlParser.create() - .parse( url ); + .parse( cls.locateResources( "xml/jakarta/simple/persistence.xml" ) ); String expectedPuName = "defaultpar"; assertThat( descriptors ).containsOnlyKeys( expectedPuName ); var descriptor = descriptors.get( expectedPuName ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/DuplicatePersistenceUnitNameTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/DuplicatePersistenceUnitNameTest.java index 5046667f64..08a91822ac 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/DuplicatePersistenceUnitNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/DuplicatePersistenceUnitNameTest.java @@ -61,32 +61,14 @@ public void tearDown() { @Test public void testDuplicatePersistenceUnitNameLogAWarnMessage() { - final Map properties = new HashMap(); - properties.put( AvailableSettings.CLASSLOADERS, Arrays.asList( new TestClassLoader() ) ); - PersistenceXmlParser.create( properties ).locatePersistenceUnits(); + PersistenceXmlParser.create().parse( List.of( + findAsResource( + "org/hibernate/jpa/test/persistenceunit/META-INF/persistence.xml" + ), + findAsResource( + "org/hibernate/jpa/test/persistenceunit/META-INF/persistenceUnitForNameDuplicationTest.xml" + ) + ) ); assertTrue( "The warn HHH015018 has not been logged ", triggerable.wasTriggered() ); } - - private static class TestClassLoader extends ClassLoader { - final List urls; - - public TestClassLoader() { - urls = Arrays.asList( - findAsResource( - "org/hibernate/jpa/test/persistenceunit/META-INF/persistence.xml" - ) - , - findAsResource( - "org/hibernate/jpa/test/persistenceunit/META-INF/persistenceUnitForNameDuplicationTest.xml" - ) - ); - } - - @Override - protected Enumeration findResources(String name) throws IOException { - return name.equals( "META-INF/persistence.xml" ) ? - Collections.enumeration( urls ) : - Collections.emptyEnumeration(); - } - } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/ExcludeUnlistedClassesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/ExcludeUnlistedClassesTest.java index 1b088439cd..d7cc371100 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/ExcludeUnlistedClassesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/ExcludeUnlistedClassesTest.java @@ -6,12 +6,14 @@ */ package org.hibernate.orm.test.jpa.persistenceunit; +import static org.hibernate.internal.util.ConfigHelper.findAsResource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.IOException; import java.net.URL; import java.util.Arrays; +import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; @@ -47,12 +49,9 @@ public class ExcludeUnlistedClassesTest extends BaseUnitTestCase { @Test public void testExcludeUnlistedClasses() { - // see src/test/resources/org/hibernate/jpa/test/persistenceunit/persistence.xml - - final Map properties = new HashMap(); - properties.put( AvailableSettings.CLASSLOADERS, Arrays.asList( new TestClassLoader() ) ); - final List parsedDescriptors = PersistenceXmlParser.create( properties ) - .locatePersistenceUnits(); + final Collection parsedDescriptors = PersistenceXmlParser.create() + .parse( List.of( findAsResource( "org/hibernate/jpa/test/persistenceunit/META-INF/persistence.xml" ) ) ) + .values(); doTest( parsedDescriptors, "ExcludeUnlistedClassesTest1", false ); doTest( parsedDescriptors, "ExcludeUnlistedClassesTest2", true ); @@ -60,7 +59,7 @@ public void testExcludeUnlistedClasses() { doTest( parsedDescriptors, "ExcludeUnlistedClassesTest4", true ); } - private void doTest(List parsedDescriptors, + private void doTest(Collection parsedDescriptors, final String persistenceUnitName, final boolean shouldExclude) { for (final PersistenceUnitDescriptor descriptor : parsedDescriptors) { if (descriptor.getName().equals( persistenceUnitName )) { @@ -70,32 +69,4 @@ private void doTest(List parsedDescriptors, } fail("Could not find the persistence unit: " + persistenceUnitName); } - - private static class TestClassLoader extends ClassLoader { - - @Override - protected Enumeration findResources(String name) throws IOException { - if (name.equals( "META-INF/persistence.xml" )) { - final URL puUrl = ConfigHelper.findAsResource( - "org/hibernate/jpa/test/persistenceunit/META-INF/persistence.xml" ); - return new Enumeration() { - boolean hasMore = true; - - @Override - public boolean hasMoreElements() { - return hasMore; - } - - @Override - public URL nextElement() { - hasMore = false; - return puUrl; - } - }; - } - else { - return java.util.Collections.emptyEnumeration(); - } - } - } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/PersistenceXmlParserTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/PersistenceXmlParserTest.java index 99b39226cb..d306c34e54 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/PersistenceXmlParserTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/persistenceunit/PersistenceXmlParserTest.java @@ -18,6 +18,7 @@ import java.util.Map; import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.AvailableSettings; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; @@ -48,10 +49,10 @@ public void create_classLoaders() { new TestClassLoader( "pu2" ), null ); - assertThat( parser.getClassLoaderService() ).isNotNull(); - assertThat( parser.locatePersistenceUnits() ) - .extracting( PersistenceUnitDescriptor::getName ) - .containsExactlyInAnyOrder( "pu1", "pu2" ); + ClassLoaderService clService = parser.getClassLoaderService(); + assertThat( clService ).isNotNull(); + assertThat( parser.parse( clService.locateResources( "META-INF/persistence.xml" ) ) ) + .containsOnlyKeys( "pu1", "pu2" ); } @Test @@ -64,36 +65,16 @@ public void create_classLoaderService() { new TestClassLoader( "pu2" ), myClassLoaderService ); - assertThat( parser.getClassLoaderService() ).isSameAs( myClassLoaderService ); - assertThat( parser.locatePersistenceUnits() ) - .extracting( PersistenceUnitDescriptor::getName ) - .containsExactlyInAnyOrder( "pu3" ); - } - - @Test - public void locatePersistenceUnits() { - var parser = PersistenceXmlParser.create( - Map.of(), - new TestClassLoader( "pu1" ), - null - ); - assertThat( parser.locatePersistenceUnits() ) - .singleElement() - .returns( "pu1", PersistenceUnitDescriptor::getName ); - } - - @Test - public void locatePersistenceUnits_empty() { - var noFileLog = logInspection.watchForLogMessages( "HHH000318" ); - var parser = PersistenceXmlParser.create(); - assertThat( parser.locatePersistenceUnits() ).isEmpty(); - assertThat( noFileLog.wasTriggered() ).isTrue(); + ClassLoaderService clService = parser.getClassLoaderService(); + assertThat( clService ).isSameAs( myClassLoaderService ); + assertThat( parser.parse( clService.locateResources( "META-INF/persistence.xml" ) ) ) + .containsOnlyKeys( "pu3" ); } @Test public void parse() { var parser = PersistenceXmlParser.create(); - var result = parser.parse( findPuResource( "multipu" ) ); + var result = parser.parse( List.of( findPuResource( "multipu" ) ) ); assertThat( result ) .containsOnlyKeys( "multipu1", "multipu2", "multipu3" ); assertThat( result.get( "multipu1" ) ) @@ -112,7 +93,7 @@ public void parse() { @Test public void parse_defaultTransactionType() { var parser = PersistenceXmlParser.create(); - var result = parser.parse( findPuResource( "multipu" ), PersistenceUnitTransactionType.JTA ); + var result = parser.parse( List.of( findPuResource( "multipu" ) ), PersistenceUnitTransactionType.JTA ); assertThat( result.get( "multipu1" ) ) .returns( "multipu1", PersistenceUnitDescriptor::getName ) .returns(