From abfe3f209d513eed28243b9d3a00eb6db4939e6e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 26 May 2016 23:57:49 +0200 Subject: [PATCH] DefaultPersistenceUnitManager can determine persistence unit root from orm.xml location Issue: SPR-14246 --- .../DefaultPersistenceUnitManager.java | 34 ++++--- .../PersistenceUnitReader.java | 89 ++++++++++--------- 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index 34ac4be069..bae326c44f 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -553,8 +553,20 @@ public class DefaultPersistenceUnitManager scannedUnit.addMappingFileName(mappingFileName); } } - else if (useOrmXmlForDefaultPersistenceUnit()) { - scannedUnit.addMappingFileName(DEFAULT_ORM_XML_RESOURCE); + else { + Resource ormXml = getOrmXmlForDefaultPersistenceUnit(); + if (ormXml != null) { + scannedUnit.addMappingFileName(DEFAULT_ORM_XML_RESOURCE); + if (scannedUnit.getPersistenceUnitRootUrl() == null) { + try { + scannedUnit.setPersistenceUnitRootUrl( + PersistenceUnitReader.determinePersistenceUnitRootUrl(ormXml)); + } + catch (IOException ex) { + logger.debug("Failed to determine persistence unit root URL from orm.xml location", ex); + } + } + } } return scannedUnit; @@ -593,27 +605,27 @@ public class DefaultPersistenceUnitManager } /** - * Determine whether to register JPA's default "META-INF/orm.xml" with - * Spring's default persistence unit, if any. - *

Checks whether a "META-INF/orm.xml" file exists in the classpath and - * uses it if it is not co-located with a "META-INF/persistence.xml" file. + * Determine JPA's default "META-INF/orm.xml" resource for use with Spring's default + * persistence unit, if any. + *

Checks whether a "META-INF/orm.xml" file exists in the classpath and uses it + * if it is not co-located with a "META-INF/persistence.xml" file. */ - private boolean useOrmXmlForDefaultPersistenceUnit() { + private Resource getOrmXmlForDefaultPersistenceUnit() { Resource ormXml = this.resourcePatternResolver.getResource( this.defaultPersistenceUnitRootLocation + DEFAULT_ORM_XML_RESOURCE); if (ormXml.exists()) { try { Resource persistenceXml = ormXml.createRelative(PERSISTENCE_XML_FILENAME); if (!persistenceXml.exists()) { - return true; + return ormXml; } } catch (IOException ex) { // Cannot resolve relative persistence.xml file - let's assume it's not there. - return true; + return ormXml; } } - return false; + return null; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java index aafa06fffc..bb4c44f046 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceUnitReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -51,7 +51,7 @@ import org.springframework.util.xml.SimpleSaxErrorHandler; * @author Juergen Hoeller * @since 2.0 */ -class PersistenceUnitReader { +final class PersistenceUnitReader { private static final String PERSISTENCE_VERSION = "version"; @@ -84,7 +84,7 @@ class PersistenceUnitReader { private static final String META_INF = "META-INF"; - private final Log logger = LogFactory.getLog(getClass()); + private static final Log logger = LogFactory.getLog(PersistenceUnitReader.class); private final ResourcePatternResolver resourcePatternResolver; @@ -185,47 +185,6 @@ class PersistenceUnitReader { return infos; } - /** - * Determine the persistence unit root URL based on the given resource - * (which points to the {@code persistence.xml} file we're reading). - * @param resource the resource to check - * @return the corresponding persistence unit root URL - * @throws IOException if the checking failed - */ - protected URL determinePersistenceUnitRootUrl(Resource resource) throws IOException { - URL originalURL = resource.getURL(); - - // If we get an archive, simply return the jar URL (section 6.2 from the JPA spec) - if (ResourceUtils.isJarURL(originalURL)) { - return ResourceUtils.extractJarFileURL(originalURL); - } - - // check META-INF folder - String urlToString = originalURL.toExternalForm(); - if (!urlToString.contains(META_INF)) { - if (logger.isInfoEnabled()) { - logger.info(resource.getFilename() + - " should be located inside META-INF directory; cannot determine persistence unit root URL for " + - resource); - } - return null; - } - if (urlToString.lastIndexOf(META_INF) == urlToString.lastIndexOf('/') - (1 + META_INF.length())) { - if (logger.isInfoEnabled()) { - logger.info(resource.getFilename() + - " is not located in the root of META-INF directory; cannot determine persistence unit root URL for " + - resource); - } - return null; - } - - String persistenceUnitRoot = urlToString.substring(0, urlToString.lastIndexOf(META_INF)); - if (persistenceUnitRoot.endsWith("/")) { - persistenceUnitRoot = persistenceUnitRoot.substring(0, persistenceUnitRoot.length() - 1); - } - return new URL(persistenceUnitRoot); - } - /** * Parse the unit info DOM element. */ @@ -365,4 +324,46 @@ class PersistenceUnitReader { } } + + /** + * Determine the persistence unit root URL based on the given resource + * (which points to the {@code persistence.xml} file we're reading). + * @param resource the resource to check + * @return the corresponding persistence unit root URL + * @throws IOException if the checking failed + */ + static URL determinePersistenceUnitRootUrl(Resource resource) throws IOException { + URL originalURL = resource.getURL(); + + // If we get an archive, simply return the jar URL (section 6.2 from the JPA spec) + if (ResourceUtils.isJarURL(originalURL)) { + return ResourceUtils.extractJarFileURL(originalURL); + } + + // Check META-INF folder + String urlToString = originalURL.toExternalForm(); + if (!urlToString.contains(META_INF)) { + if (logger.isInfoEnabled()) { + logger.info(resource.getFilename() + + " should be located inside META-INF directory; cannot determine persistence unit root URL for " + + resource); + } + return null; + } + if (urlToString.lastIndexOf(META_INF) == urlToString.lastIndexOf('/') - (1 + META_INF.length())) { + if (logger.isInfoEnabled()) { + logger.info(resource.getFilename() + + " is not located in the root of META-INF directory; cannot determine persistence unit root URL for " + + resource); + } + return null; + } + + String persistenceUnitRoot = urlToString.substring(0, urlToString.lastIndexOf(META_INF)); + if (persistenceUnitRoot.endsWith("/")) { + persistenceUnitRoot = persistenceUnitRoot.substring(0, persistenceUnitRoot.length() - 1); + } + return new URL(persistenceUnitRoot); + } + }