1
1
/*
2
- * Copyright 2002-2013 the original author or authors.
2
+ * Copyright 2002-2014 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
69
69
* with configurable file locations, JDBC DataSource lookup and load-time weaving.
70
70
*
71
71
* <p>The default XML file location is {@code classpath*:META-INF/persistence.xml},
72
- * scanning for all matching files in the class path (as defined in the JPA specification).
72
+ * scanning for all matching files in the classpath (as defined in the JPA specification).
73
73
* DataSource names are by default interpreted as JNDI names, and no load time weaving
74
74
* is available (which requires weaving to be turned off in the persistence provider).
75
75
*
86
86
public class DefaultPersistenceUnitManager
87
87
implements PersistenceUnitManager , ResourceLoaderAware , LoadTimeWeaverAware , InitializingBean {
88
88
89
+ private static final String ENTITY_CLASS_RESOURCE_PATTERN = "/**/*.class" ;
90
+
91
+ private static final String DEFAULT_ORM_XML_RESOURCE = "META-INF/orm.xml" ;
92
+
93
+ private static final String PERSISTENCE_XML_FILENAME = "persistence.xml" ;
94
+
89
95
/**
90
96
* Default location of the {@code persistence.xml} file:
91
97
* "classpath*:META-INF/persistence.xml".
92
98
*/
93
- public final static String DEFAULT_PERSISTENCE_XML_LOCATION = "classpath*:META-INF/persistence.xml" ;
99
+ public final static String DEFAULT_PERSISTENCE_XML_LOCATION = "classpath*:META-INF/" + PERSISTENCE_XML_FILENAME ;
94
100
95
101
/**
96
102
* Default location for the persistence unit root URL:
97
- * "classpath:", indicating the root of the class path .
103
+ * "classpath:", indicating the root of the classpath .
98
104
*/
99
105
public final static String ORIGINAL_DEFAULT_PERSISTENCE_UNIT_ROOT_LOCATION = "classpath:" ;
100
106
101
107
public final static String ORIGINAL_DEFAULT_PERSISTENCE_UNIT_NAME = "default" ;
102
108
103
- private static final String ENTITY_CLASS_RESOURCE_PATTERN = "/**/*.class" ;
104
-
105
109
106
110
private static final Set <TypeFilter > entityTypeFilters ;
107
111
@@ -178,9 +182,9 @@ public void setPersistenceXmlLocations(String... persistenceXmlLocations) {
178
182
/**
179
183
* Set the default persistence unit root location, to be applied
180
184
* if no unit-specific persistence unit root could be determined.
181
- * <p>Default is "classpath:", that is, the root of the current class path
185
+ * <p>Default is "classpath:", that is, the root of the current classpath
182
186
* (nearest root directory). To be overridden if unit-specific resolution
183
- * does not work and the class path root is not appropriate either.
187
+ * does not work and the classpath root is not appropriate either.
184
188
*/
185
189
public void setDefaultPersistenceUnitRootLocation (String defaultPersistenceUnitRootLocation ) {
186
190
this .defaultPersistenceUnitRootLocation = defaultPersistenceUnitRootLocation ;
@@ -205,6 +209,18 @@ public void setDefaultPersistenceUnitName(String defaultPersistenceUnitName) {
205
209
* <p>Default is none. Specify packages to search for autodetection of your entity
206
210
* classes in the classpath. This is analogous to Spring's component-scan feature
207
211
* ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}).
212
+ * <p>Such package scanning defines a "default persistence unit" in Spring, which
213
+ * may live next to regularly defined units originating from {@code persistence.xml}.
214
+ * Its name is determined by {@link #setDefaultPersistenceUnitName}: by default,
215
+ * it's simply "default".
216
+ * <p>If no explicit {@link #setMappingResources mapping resources} have been
217
+ * specified in addition to these packages, this manager looks for a default
218
+ * {@code META-INF/orm.xml} file in the classpath, registering it as a mapping
219
+ * resource for the default unit if the mapping file is not co-located with a
220
+ * {@code persistence.xml} file (in which case we assume it is only meant to be
221
+ * used with the persistence units defined there, like in standard JPA).
222
+ * @see #setDefaultPersistenceUnitName
223
+ * @see #setMappingResources
208
224
*/
209
225
public void setPackagesToScan (String ... packagesToScan ) {
210
226
this .packagesToScan = packagesToScan ;
@@ -218,6 +234,17 @@ public void setPackagesToScan(String... packagesToScan) {
218
234
* <p>Note that mapping resources must be relative to the classpath root,
219
235
* e.g. "META-INF/mappings.xml" or "com/mycompany/repository/mappings.xml",
220
236
* so that they can be loaded through {@code ClassLoader.getResource}.
237
+ * <p>If no explicit mapping resources have been specified next to
238
+ * {@link #setPackagesToScan packages to scan}, this manager looks for a default
239
+ * {@code META-INF/orm.xml} file in the classpath, registering it as a mapping
240
+ * resource for the default unit if the mapping file is not co-located with a
241
+ * {@code persistence.xml} file (in which case we assume it is only meant to be
242
+ * used with the persistence units defined there, like in standard JPA).
243
+ * <p>Note that specifying an empty array/list here suppresses the default
244
+ * {@code META-INF/orm.xml} check. On the other hand, explicitly specifying
245
+ * {@code META-INF/orm.xml} here will register that file even if it happens
246
+ * to be co-located with a {@code persistence.xml} file.
247
+ * @see #setDefaultPersistenceUnitName
221
248
* @see #setPackagesToScan
222
249
*/
223
250
public void setMappingResources (String ... mappingResources ) {
@@ -480,6 +507,7 @@ private SpringPersistenceUnitInfo buildDefaultPersistenceUnitInfo() {
480
507
SpringPersistenceUnitInfo scannedUnit = new SpringPersistenceUnitInfo ();
481
508
scannedUnit .setPersistenceUnitName (this .defaultPersistenceUnitName );
482
509
scannedUnit .setExcludeUnlistedClasses (true );
510
+
483
511
if (this .packagesToScan != null ) {
484
512
for (String pkg : this .packagesToScan ) {
485
513
try {
@@ -508,11 +536,16 @@ private SpringPersistenceUnitInfo buildDefaultPersistenceUnitInfo() {
508
536
}
509
537
}
510
538
}
539
+
511
540
if (this .mappingResources != null ) {
512
541
for (String mappingFileName : this .mappingResources ) {
513
542
scannedUnit .addMappingFileName (mappingFileName );
514
543
}
515
544
}
545
+ else if (useOrmXmlForDefaultPersistenceUnit ()) {
546
+ scannedUnit .addMappingFileName (DEFAULT_ORM_XML_RESOURCE );
547
+ }
548
+
516
549
return scannedUnit ;
517
550
}
518
551
@@ -548,6 +581,30 @@ private URL determineDefaultPersistenceUnitRootUrl() {
548
581
}
549
582
}
550
583
584
+ /**
585
+ * Determine whether to register JPA's default "META-INF/orm.xml" with
586
+ * Spring's default persistence unit, if any.
587
+ * <p>Checks whether a "META-INF/orm.xml" file exists in the classpath and
588
+ * uses it if it is not co-located with a "META-INF/persistence.xml" file.
589
+ */
590
+ private boolean useOrmXmlForDefaultPersistenceUnit () {
591
+ Resource ormXml = this .resourcePatternResolver .getResource (
592
+ this .defaultPersistenceUnitRootLocation + DEFAULT_ORM_XML_RESOURCE );
593
+ if (ormXml .exists ()) {
594
+ try {
595
+ Resource persistenceXml = ormXml .createRelative (PERSISTENCE_XML_FILENAME );
596
+ if (!persistenceXml .exists ()) {
597
+ return true ;
598
+ }
599
+ }
600
+ catch (IOException ex ) {
601
+ // Cannot resolve relative persistence.xml file - let's assume it's not there.
602
+ return true ;
603
+ }
604
+ }
605
+ return false ;
606
+ }
607
+
551
608
552
609
/**
553
610
* Return the specified PersistenceUnitInfo from this manager's cache
0 commit comments