DefaultPersistenceUnitManager can determine persistence unit root from orm.xml location

Issue: SPR-14246
This commit is contained in:
Juergen Hoeller
2016-05-26 23:57:49 +02:00
parent a979885d17
commit abfe3f209d
2 changed files with 68 additions and 55 deletions

View File

@@ -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.
* <p>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.
* <p>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;
}

View File

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