Spec updates draft 11
diff --git a/src/javax/persistence/Convert.java b/src/javax/persistence/Convert.java
index 6fed181..9fe4086 100644
--- a/src/javax/persistence/Convert.java
+++ b/src/javax/persistence/Convert.java
@@ -10,7 +10,6 @@
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
- * Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
package javax.persistence;
diff --git a/src/javax/persistence/Converter.java b/src/javax/persistence/Converter.java
index b4093ab..d9916c4 100644
--- a/src/javax/persistence/Converter.java
+++ b/src/javax/persistence/Converter.java
@@ -10,7 +10,6 @@
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
- * Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
package javax.persistence;
diff --git a/src/javax/persistence/Converts.java b/src/javax/persistence/Converts.java
index ac158f4..c0aa398 100644
--- a/src/javax/persistence/Converts.java
+++ b/src/javax/persistence/Converts.java
@@ -10,7 +10,6 @@
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
- * Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
package javax.persistence;
diff --git a/src/javax/persistence/EntityManager.java b/src/javax/persistence/EntityManager.java
index 193e95e..a853e11 100644
--- a/src/javax/persistence/EntityManager.java
+++ b/src/javax/persistence/EntityManager.java
@@ -16,6 +16,7 @@
package javax.persistence;
import java.util.Map;
+import java.util.List;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@@ -80,6 +81,42 @@
public <T> T merge(T entity);
/**
+ * Merge the state of the given entity into the current
+ * persistence context using the EntityGraph as a template for
+ * applying the merge operation.
+ * @param entity entity instance
+ * @param entityGraph the entity graph template to be used for the
+ * merge operation
+ * @param properties provider-specific hints. If an implementation
+ * does not recognize a hint, it must be ignored.
+ * @return the managed instance that the state was merged to
+ * @throws IllegalArgumentException if the instance is not an entity,
+ * is a removed entity
+ * @throws TransactionRequiredException if there is no transaction
+ * when invoked on a container-managed entity manager that
+ * is of type <code>PersistenceContextType.TRANSACTION</code>
+ * @since Java Persistence 2.1
+ */
+ public <T> T merge(T entity, EntityGraph<? super T> entityGraph, Map<String, Object> properties);
+
+ /**
+ * Copy the provided entity graph using the EntityGraph argument
+ * as a template to specify the attributes that will be copied.
+ * Attributes not included in the EntityGraph argument will not be
+ * copied.
+ * @param entity entity instance
+ * @param entityGraph the entity graph template to be used for
+ * the copy operation
+ * @param properties provider-specific hints. If an implementation
+ * does not recognize a hint, it must be ignored.
+ * @return copy of the entity
+ * @throws IllegalArgumentException if the instance is not an entity
+ *
+ * @since Java Persistence 2.1
+ */
+public <T> T copy(T entity, EntityGraph<? super T> entityGraph, Map<String, Object> properties);
+
+ /**
* Remove the entity instance.
* @param entity entity instance
* @throws IllegalArgumentException if the instance is not an
@@ -102,7 +139,7 @@
* not exist
* @throws IllegalArgumentException if the first argument does
* not denote an entity type or the second argument is
- * is not a valid type for that entitys primary key or
+ * is not a valid type for that entity's primary key or
* is null
*/
public <T> T find(Class<T> entityClass, Object primaryKey);
@@ -122,7 +159,7 @@
* not exist
* @throws IllegalArgumentException if the first argument does
* not denote an entity type or the second argument is
- * is not a valid type for that entitys primary key or
+ * is not a valid type for that entity's primary key or
* is null
* @since Java Persistence 2.0
*/
@@ -850,4 +887,44 @@
* @since Java Persistence 2.0
*/
public Metamodel getMetamodel();
+
+ /**
+ * Return a mutable EntityGraph that can be used to dynamically create an
+ * EntityGraph.
+ * @param rootType class of entity graph
+ * @return entity graph
+ * @since Java Persistence 2.1
+ */
+ public <T> EntityGraph<T> createEntityGraph(Class<T> rootType);
+
+ /**
+ * Return a mutable copy of the named EntityGraph. If there
+ * is no entity graph with the specified name, null is returned.
+ * @param graphName name of an entity graph
+ * @return entity graph
+ * @since Java Persistence 2.1
+ */
+ public EntityGraph<?> createEntityGraph(String graphName);
+
+ /**
+ * Return a named EntityGraph. The returned EntityGraph
+ * should be considered immutable.
+ * @param graphName name of an existing entity graph
+ * @return named entity graph
+ * @throws IllegalArgumentException if there is no EntityGraph of
+ * the given name
+ * @since Java Persistence 2.1
+ */
+ public <T> EntityGraph<T> getEntityGraph(String graphName);
+
+ /**
+ * Return all named EntityGraphs that have been defined for the provided
+ * class type.
+ * @param entityClass entity class
+ * @return list of all entity graphs defined for the entity
+ * @throws IllegalArgumentException if the class is not an entity
+ * @since Java Persistence 2.1
+ */
+ public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass);
+
}
diff --git a/src/javax/persistence/EntityManagerFactory.java b/src/javax/persistence/EntityManagerFactory.java
index 5932f80..b4d534c 100644
--- a/src/javax/persistence/EntityManagerFactory.java
+++ b/src/javax/persistence/EntityManagerFactory.java
@@ -207,4 +207,14 @@
*/
public <T> T unwrap(Class<T> cls);
+ /**
+ * Add a named copy of the EntityGraph to the
+ * EntityManagerFactory. If an entity graph with the same name
+ * already exists, it is replaced.
+ * @param graphName name for the entity graph
+ * @param entityGraph entity graph
+ * @since Java Persistence 2.1
+ */
+ public <T> void addNamedEntityGraph(String graphName, EntityGraph<T> entityGraph);
+
}
diff --git a/src/javax/persistence/MapsId.java b/src/javax/persistence/MapsId.java
index 9c821e1..9e4e111 100644
--- a/src/javax/persistence/MapsId.java
+++ b/src/javax/persistence/MapsId.java
@@ -71,7 +71,7 @@
/**
* (Optional) The name of the attribute within the composite key
* to which the relationship attribute corresponds. If not
- * supplied, the relationship maps the entitys primary
+ * supplied, the relationship maps the entity's primary
* key.
*/
String value() default ""; }
diff --git a/src/javax/persistence/Persistence.java b/src/javax/persistence/Persistence.java
index 74bdfb8..cefc978 100644
--- a/src/javax/persistence/Persistence.java
+++ b/src/javax/persistence/Persistence.java
@@ -87,7 +87,6 @@
return emf;
}
-
/**
* Create database schemas and/or tables and/or create DDL
* scripts as determined by the supplied properties.
@@ -107,10 +106,18 @@
* @since Java Persistence 2.1
*/
public static void generateSchema(String persistenceUnitName, Map map) {
-
+ PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();
+ List<PersistenceProvider> providers = resolver.getPersistenceProviders();
+
+ for (PersistenceProvider provider : providers) {
+ if (provider.generateSchema(persistenceUnitName, map)) {
+ return;
+ }
+ }
+
+ throw new PersistenceException("No Persistence provider to generate schema named " + persistenceUnitName);
}
-
/**
* Return the PersistenceUtil instance
* @return PersistenceUtil instance
diff --git a/src/javax/persistence/criteria/Fetch.java b/src/javax/persistence/criteria/Fetch.java
index 0f72e31..310cb3a 100644
--- a/src/javax/persistence/criteria/Fetch.java
+++ b/src/javax/persistence/criteria/Fetch.java
@@ -28,36 +28,6 @@
public interface Fetch<Z, X> extends FetchParent<Z, X> {
/**
- * Modify the fetch join to restrict the result according to
- * the specified ON condition and return the fetch join object.
- * Replaces the previous ON condition, if any.
- * @param restriction a simple or compound boolean expression
- * @return the modified fetch join object
- * @since Java Persistence 2.1
- */
- Fetch<Z, X> on(Expression<Boolean> restriction);
-
-
- /**
- * Modify the fetch join to restrict the result according to
- * the specified ON condition and return the fetch join object.
- * Replaces the previous ON condition, if any.
- * @param restrictions zero or more restriction predicates
- * @return the modified fetch join object
- * @since Java Persistence 2.1
- */
- Fetch<Z, X> on(Predicate... restrictions);
-
- /**
- * Return the predicate that corresponds to the ON
- * restriction(s), or null if no ON condition has been
- * specified.
- * @return the ON restriction predicate
- * @since Java Persistence 2.1
- */
- Predicate getOn();
-
- /**
* Return the metamodel attribute corresponding to the
* fetch join.
* @return metamodel attribute for the join
diff --git a/src/javax/persistence/orm_2_1.xsd b/src/javax/persistence/orm_2_1.xsd
index cbc5185..4703523 100644
--- a/src/javax/persistence/orm_2_1.xsd
+++ b/src/javax/persistence/orm_2_1.xsd
@@ -1,44 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Java Persistence API object/relational mapping file schema -->
-<xsd:schema targetNamespace="http://java.sun.com/xml/ns/persistence/orm"
- xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified"
+<xsd:schema targetNamespace="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
version="2.1">
<xsd:annotation>
<xsd:documentation>
- @(#)orm_2_1.xsd 2.1 September 12 2012
+ @(#)orm_2_1.xsd 2.1 December 11 2012
</xsd:documentation>
</xsd:annotation>
<xsd:annotation>
<xsd:documentation>
- Copyright (c) 2008 - 2012 Oracle Corporation. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- which accompanies this distribution.
+ Copyright (c) 2008 - 2012 Oracle Corporation. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ which accompanies this distribution.
The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- and the Eclipse Distribution License is available at
+ and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
-
+
Contributors:
- Linda DeMichiel - Java Persistence 2.1, Version 2.1 (September 12, 2012)
+ Linda DeMichiel - Java Persistence 2.1, Version 2.1 (November 9, 2012)
Specification available from http://jcp.org/en/jsr/detail?id=338
-
+
</xsd:documentation>
</xsd:annotation>
<xsd:annotation>
<xsd:documentation><![CDATA[
- This is the XML Schema for the persistence object/relational
+ This is the XML Schema for the persistence object/relational
mapping file.
- The file may be named "META-INF/orm.xml" in the persistence
- archive or it may be named some other name which would be
+ The file may be named "META-INF/orm.xml" in the persistence
+ archive or it may be named some other name which would be
used to locate the file as resource on the classpath.
Object/relational mapping files must indicate the object/relational
@@ -82,19 +82,19 @@
1. The persistence-unit-metadata element contains metadata
for the entire persistence unit. It is undefined if this element
occurs in multiple mapping files within the same persistence unit.
-
+
2. The package, schema, catalog and access elements apply to all of
the entity, mapped-superclass and embeddable elements defined in
the same file in which they occur.
3. The sequence-generator, table-generator, converter, named-query,
- named-native-query, named-stored-procedure-query, and
+ named-native-query, named-stored-procedure-query, and
sql-result-set-mapping elements are global to the persistence
unit. It is undefined to have more than one sequence-generator
or table-generator of the same name in the same or different
mapping files in a persistence unit. It is undefined to have
more than one named-query, named-native-query, sql-result-set-mapping,
- or named-stored-procedure-query of the same name in the same
+ or named-stored-procedure-query of the same name in the same
or different mapping files in a persistence unit. It is also
undefined to have more than one converter for the same target
type in the same or different mapping files in a persistence unit.
@@ -109,7 +109,7 @@
<xsd:sequence>
<xsd:element name="description" type="xsd:string"
minOccurs="0"/>
- <xsd:element name="persistence-unit-metadata"
+ <xsd:element name="persistence-unit-metadata"
type="orm:persistence-unit-metadata"
minOccurs="0"/>
<xsd:element name="package" type="xsd:string"
@@ -122,28 +122,28 @@
minOccurs="0"/>
<xsd:element name="sequence-generator" type="orm:sequence-generator"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="table-generator" type="orm:table-generator"
+ <xsd:element name="table-generator" type="orm:table-generator"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="named-query" type="orm:named-query"
+ <xsd:element name="named-query" type="orm:named-query"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="named-native-query" type="orm:named-native-query"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="named-stored-procedure-query"
+ <xsd:element name="named-stored-procedure-query"
type="orm:named-stored-procedure-query"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="sql-result-set-mapping"
- type="orm:sql-result-set-mapping"
+ <xsd:element name="sql-result-set-mapping"
+ type="orm:sql-result-set-mapping"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="mapped-superclass" type="orm:mapped-superclass"
+ <xsd:element name="mapped-superclass" type="orm:mapped-superclass"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="entity" type="orm:entity"
+ <xsd:element name="entity" type="orm:entity"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="embeddable" type="orm:embeddable"
+ <xsd:element name="embeddable" type="orm:embeddable"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="converter" type="orm:converter"
+ <xsd:element name="converter" type="orm:converter"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
- <xsd:attribute name="version" type="orm:versionType"
+ <xsd:attribute name="version" type="orm:versionType"
fixed="2.1" use="required"/>
</xsd:complexType>
</xsd:element>
@@ -154,11 +154,11 @@
<xsd:annotation>
<xsd:documentation>
- Metadata that applies to the persistence unit and not just to
- the mapping file in which it is contained.
+ Metadata that applies to the persistence unit and not just to
+ the mapping file in which it is contained.
If the xml-mapping-metadata-complete element is specified,
- the complete set of mapping metadata for the persistence unit
+ the complete set of mapping metadata for the persistence unit
is contained in the XML mapping files for the persistence unit.
</xsd:documentation>
@@ -167,7 +167,7 @@
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="xml-mapping-metadata-complete" type="orm:emptyType"
minOccurs="0"/>
- <xsd:element name="persistence-unit-defaults"
+ <xsd:element name="persistence-unit-defaults"
type="orm:persistence-unit-defaults"
minOccurs="0"/>
</xsd:sequence>
@@ -179,15 +179,15 @@
<xsd:annotation>
<xsd:documentation>
- These defaults are applied to the persistence unit as a whole
- unless they are overridden by local annotation or XML
- element settings.
-
+ These defaults are applied to the persistence unit as a whole
+ unless they are overridden by local annotation or XML
+ element settings.
+
schema - Used as the schema for all tables, secondary tables, join
- tables, collection tables, sequence generators, and table
+ tables, collection tables, sequence generators, and table
generators that apply to the persistence unit
catalog - Used as the catalog for all tables, secondary tables, join
- tables, collection tables, sequence generators, and table
+ tables, collection tables, sequence generators, and table
generators that apply to the persistence unit
delimited-identifiers - Used to treat database identifiers as
delimited identifiers.
@@ -195,8 +195,8 @@
the persistence unit
cascade-persist - Adds cascade-persist to the set of cascade options
in all entity relationships of the persistence unit
- entity-listeners - List of default entity listeners to be invoked
- on each entity in the persistence unit.
+ entity-listeners - List of default entity listeners to be invoked
+ on each entity in the persistence unit.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
@@ -205,11 +205,11 @@
minOccurs="0"/>
<xsd:element name="catalog" type="xsd:string"
minOccurs="0"/>
- <xsd:element name="delimited-identifiers" type="orm:emptyType"
+ <xsd:element name="delimited-identifiers" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="access" type="orm:access-type"
minOccurs="0"/>
- <xsd:element name="cascade-persist" type="orm:emptyType"
+ <xsd:element name="cascade-persist" type="orm:emptyType"
minOccurs="0"/>
<xsd:element name="entity-listeners" type="orm:entity-listeners"
minOccurs="0"/>
@@ -224,10 +224,10 @@
Defines the settings and mappings for an entity. Is allowed to be
sparsely populated and used in conjunction with the annotations.
- Alternatively, the metadata-complete attribute can be used to
+ Alternatively, the metadata-complete attribute can be used to
indicate that no annotations on the entity class (and its fields
- or properties) are to be processed. If this is the case then
- the defaulting rules for the entity and its subelements will
+ or properties) are to be processed. If this is the case then
+ the defaulting rules for the entity and its subelements will
be recursively applied.
@Target(TYPE) @Retention(RUNTIME)
@@ -239,60 +239,62 @@
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
- <xsd:element name="table" type="orm:table"
+ <xsd:element name="table" type="orm:table"
minOccurs="0"/>
- <xsd:element name="secondary-table" type="orm:secondary-table"
+ <xsd:element name="secondary-table" type="orm:secondary-table"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:sequence>
- <xsd:element name="primary-key-join-column"
- type="orm:primary-key-join-column"
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="primary-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="primary-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
<xsd:element name="id-class" type="orm:id-class" minOccurs="0"/>
<xsd:element name="inheritance" type="orm:inheritance" minOccurs="0"/>
- <xsd:element name="discriminator-value" type="orm:discriminator-value"
+ <xsd:element name="discriminator-value" type="orm:discriminator-value"
minOccurs="0"/>
- <xsd:element name="discriminator-column"
- type="orm:discriminator-column"
+ <xsd:element name="discriminator-column"
+ type="orm:discriminator-column"
minOccurs="0"/>
- <xsd:element name="sequence-generator" type="orm:sequence-generator"
+ <xsd:element name="sequence-generator" type="orm:sequence-generator"
minOccurs="0"/>
- <xsd:element name="table-generator" type="orm:table-generator"
+ <xsd:element name="table-generator" type="orm:table-generator"
minOccurs="0"/>
- <xsd:element name="named-query" type="orm:named-query"
+ <xsd:element name="named-query" type="orm:named-query"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="named-native-query" type="orm:named-native-query"
+ <xsd:element name="named-native-query" type="orm:named-native-query"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="named-stored-procedure-query"
- type="orm:named-stored-procedure-query"
+ type="orm:named-stored-procedure-query"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="sql-result-set-mapping"
- type="orm:sql-result-set-mapping"
+ <xsd:element name="sql-result-set-mapping"
+ type="orm:sql-result-set-mapping"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="exclude-default-listeners" type="orm:emptyType"
+ <xsd:element name="exclude-default-listeners" type="orm:emptyType"
minOccurs="0"/>
- <xsd:element name="exclude-superclass-listeners" type="orm:emptyType"
+ <xsd:element name="exclude-superclass-listeners" type="orm:emptyType"
minOccurs="0"/>
- <xsd:element name="entity-listeners" type="orm:entity-listeners"
+ <xsd:element name="entity-listeners" type="orm:entity-listeners"
minOccurs="0"/>
<xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
- <xsd:element name="post-persist" type="orm:post-persist"
+ <xsd:element name="post-persist" type="orm:post-persist"
minOccurs="0"/>
<xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
<xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
<xsd:element name="pre-update" type="orm:pre-update" minOccurs="0"/>
<xsd:element name="post-update" type="orm:post-update" minOccurs="0"/>
<xsd:element name="post-load" type="orm:post-load" minOccurs="0"/>
- <xsd:element name="attribute-override" type="orm:attribute-override"
+ <xsd:element name="attribute-override" type="orm:attribute-override"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="association-override"
+ <xsd:element name="association-override"
type="orm:association-override"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="convert" type="orm:convert"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="named-entity-graph" type="orm:named-entity-graph"
+ minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="attributes" type="orm:attributes" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
@@ -340,7 +342,7 @@
<xsd:sequence>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
<xsd:element name="join-table" type="orm:join-table"
@@ -388,9 +390,9 @@
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:choice>
- <xsd:element name="id" type="orm:id"
+ <xsd:element name="id" type="orm:id"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="embedded-id" type="orm:embedded-id"
+ <xsd:element name="embedded-id" type="orm:embedded-id"
minOccurs="0"/>
</xsd:choice>
<xsd:element name="basic" type="orm:basic"
@@ -403,9 +405,9 @@
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="one-to-one" type="orm:one-to-one"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="many-to-many" type="orm:many-to-many"
+ <xsd:element name="many-to-many" type="orm:many-to-many"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="element-collection" type="orm:element-collection"
+ <xsd:element name="element-collection" type="orm:element-collection"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="embedded" type="orm:embedded"
minOccurs="0" maxOccurs="unbounded"/>
@@ -489,14 +491,14 @@
</xsd:annotation>
<xsd:sequence>
<xsd:sequence>
- <xsd:element name="join-column" type="orm:join-column"
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
- <xsd:element name="unique-constraint" type="orm:unique-constraint"
+ <xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="index" type="orm:index"
+ <xsd:element name="index" type="orm:index"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
@@ -572,7 +574,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="column" type="orm:column-result"
+ <xsd:element name="column" type="orm:column-result"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="target-class" type="xsd:string" use="required"/>
@@ -726,8 +728,8 @@
<xsd:element name="map-key-join-column"
type="orm:map-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="map-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="map-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
@@ -774,11 +776,11 @@
<xsd:annotation>
<xsd:documentation>
- Defines the settings and mappings for embeddable objects. Is
- allowed to be sparsely populated and used in conjunction with
- the annotations. Alternatively, the metadata-complete attribute
- can be used to indicate that no annotations are to be processed
- in the class. If this is the case then the defaulting rules will
+ Defines the settings and mappings for embeddable objects. Is
+ allowed to be sparsely populated and used in conjunction with
+ the annotations. Alternatively, the metadata-complete attribute
+ can be used to indicate that no annotations are to be processed
+ in the class. If this is the case then the defaulting rules will
be recursively applied.
@Target({TYPE}) @Retention(RUNTIME)
@@ -788,7 +790,7 @@
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
- <xsd:element name="attributes" type="orm:embeddable-attributes"
+ <xsd:element name="attributes" type="orm:embeddable-attributes"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="class" type="xsd:string" use="required"/>
@@ -800,7 +802,7 @@
<xsd:complexType name="embeddable-attributes">
<xsd:sequence>
- <xsd:element name="basic" type="orm:basic"
+ <xsd:element name="basic" type="orm:basic"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="many-to-one" type="orm:many-to-one"
minOccurs="0" maxOccurs="unbounded"/>
@@ -808,13 +810,13 @@
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="one-to-one" type="orm:one-to-one"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="many-to-many" type="orm:many-to-many"
+ <xsd:element name="many-to-many" type="orm:many-to-many"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="element-collection" type="orm:element-collection"
+ <xsd:element name="element-collection" type="orm:element-collection"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="embedded" type="orm:embedded"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="transient" type="orm:transient"
+ <xsd:element name="transient" type="orm:transient"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
@@ -831,9 +833,9 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="attribute-override" type="orm:attribute-override"
+ <xsd:element name="attribute-override" type="orm:attribute-override"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="association-override"
+ <xsd:element name="association-override"
type="orm:association-override"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="convert" type="orm:convert"
@@ -855,7 +857,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="attribute-override" type="orm:attribute-override"
+ <xsd:element name="attribute-override" type="orm:attribute-override"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -876,7 +878,7 @@
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
- <xsd:element name="post-persist" type="orm:post-persist"
+ <xsd:element name="post-persist" type="orm:post-persist"
minOccurs="0"/>
<xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
<xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
@@ -901,7 +903,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="entity-listener" type="orm:entity-listener"
+ <xsd:element name="entity-listener" type="orm:entity-listener"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
@@ -922,7 +924,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="field-result" type="orm:field-result"
+ <xsd:element name="field-result" type="orm:field-result"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="entity-class" type="xsd:string" use="required"/>
@@ -1069,13 +1071,13 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="column" type="orm:column"
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
<xsd:element name="generated-value" type="orm:generated-value"
minOccurs="0"/>
- <xsd:element name="temporal" type="orm:temporal"
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
- <xsd:element name="table-generator" type="orm:table-generator"
+ <xsd:element name="table-generator" type="orm:table-generator"
minOccurs="0"/>
<xsd:element name="sequence-generator" type="orm:sequence-generator"
minOccurs="0"/>
@@ -1209,20 +1211,20 @@
</xsd:annotation>
<xsd:sequence>
<xsd:sequence>
- <xsd:element name="join-column" type="orm:join-column"
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
<xsd:sequence>
- <xsd:element name="inverse-join-column" type="orm:join-column"
+ <xsd:element name="inverse-join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="inverse-foreign-key" type="orm:foreign-key"
+ <xsd:element name="inverse-foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
- <xsd:element name="unique-constraint" type="orm:unique-constraint"
+ <xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="index" type="orm:index"
+ <xsd:element name="index" type="orm:index"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
@@ -1317,8 +1319,8 @@
<xsd:element name="map-key-join-column"
type="orm:map-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="map-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="map-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
@@ -1353,17 +1355,17 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:choice>
+ <xsd:choice>
<xsd:sequence>
- <xsd:element name="join-column" type="orm:join-column"
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
- <xsd:element name="join-table" type="orm:join-table"
+ <xsd:element name="join-table" type="orm:join-table"
minOccurs="0"/>
- </xsd:choice>
- <xsd:element name="cascade" type="orm:cascade-type"
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -1478,11 +1480,11 @@
<xsd:annotation>
<xsd:documentation>
- Defines the settings and mappings for a mapped superclass. Is
- allowed to be sparsely populated and used in conjunction with
- the annotations. Alternatively, the metadata-complete attribute
- can be used to indicate that no annotations are to be processed
- If this is the case then the defaulting rules will be recursively
+ Defines the settings and mappings for a mapped superclass. Is
+ allowed to be sparsely populated and used in conjunction with
+ the annotations. Alternatively, the metadata-complete attribute
+ can be used to indicate that no annotations are to be processed
+ If this is the case then the defaulting rules will be recursively
applied.
@Target(TYPE) @Retention(RUNTIME)
@@ -1493,14 +1495,14 @@
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="id-class" type="orm:id-class" minOccurs="0"/>
- <xsd:element name="exclude-default-listeners" type="orm:emptyType"
+ <xsd:element name="exclude-default-listeners" type="orm:emptyType"
minOccurs="0"/>
- <xsd:element name="exclude-superclass-listeners" type="orm:emptyType"
+ <xsd:element name="exclude-superclass-listeners" type="orm:emptyType"
minOccurs="0"/>
- <xsd:element name="entity-listeners" type="orm:entity-listeners"
+ <xsd:element name="entity-listeners" type="orm:entity-listeners"
minOccurs="0"/>
<xsd:element name="pre-persist" type="orm:pre-persist" minOccurs="0"/>
- <xsd:element name="post-persist" type="orm:post-persist"
+ <xsd:element name="post-persist" type="orm:post-persist"
minOccurs="0"/>
<xsd:element name="pre-remove" type="orm:pre-remove" minOccurs="0"/>
<xsd:element name="post-remove" type="orm:post-remove" minOccurs="0"/>
@@ -1516,6 +1518,62 @@
<!-- **************************************************** -->
+ <xsd:complexType name="named-attribute-node">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface NamedAttributeNode {
+ String value();
+ String subgraph() default "";
+ String keySubgraph() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="subgraph" type="xsd:string"/>
+ <xsd:attribute name="key-subgraph" type="xsd:string"/>
+ </xsd:complexType>
+
+<!-- **************************************************** -->
+
+ <xsd:complexType name="named-entity-graph">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface NamedEntityGraph {
+ String name() default "";
+ NamedAttributeNode[] attributeNodes() default {};
+ boolean includeAllAttributes() default false;
+ NamedSubgraph[] subgraphs() default {};
+ NamedSubGraph[] subclassSubgraphs() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="named-attribute-node"
+ type="orm:named-attribute-node"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="subgraph"
+ type="orm:named-subgraph"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="subclass-subgraph"
+ type="orm:named-subgraph"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="include-all-attributes" type="xsd:boolean"/>
+ </xsd:complexType>
+
+
+<!-- **************************************************** -->
+
<xsd:complexType name="named-native-query">
<xsd:annotation>
<xsd:documentation>
@@ -1534,7 +1592,7 @@
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="query" type="xsd:string"/>
- <xsd:element name="hint" type="orm:query-hint"
+ <xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -1562,7 +1620,7 @@
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="query" type="xsd:string"/>
<xsd:element name="lock-mode" type="orm:lock-mode-type" minOccurs="0"/>
- <xsd:element name="hint" type="orm:query-hint"
+ <xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -1588,14 +1646,14 @@
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
- <xsd:element name="stored-procedure-parameter"
- type="orm:stored-procedure-parameter"
+ <xsd:element name="parameter"
+ type="orm:stored-procedure-parameter"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="result-class" type="xsd:string"
+ <xsd:element name="result-class" type="xsd:string"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="result-set-mapping" type="xsd:string"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="hint" type="orm:query-hint"
+ <xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -1604,6 +1662,31 @@
<!-- **************************************************** -->
+ <xsd:complexType name="named-subgraph">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface NamedSubgraph {
+ String name();
+ Class type() default void.class;
+ NamedAttributeNode[] attributeNodes();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="named-attribute-node"
+ type="orm:named-attribute-node"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="class" type="xsd:string"/>
+ </xsd:complexType>
+
+<!-- **************************************************** -->
+
<xsd:complexType name="one-to-many">
<xsd:annotation>
<xsd:documentation>
@@ -1653,8 +1736,8 @@
<xsd:element name="map-key-join-column"
type="orm:map-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="map-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="map-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
@@ -1666,7 +1749,7 @@
<xsd:sequence>
<xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
@@ -1702,23 +1785,23 @@
<xsd:sequence>
<xsd:choice>
<xsd:sequence>
- <xsd:element name="primary-key-join-column"
- type="orm:primary-key-join-column"
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="primary-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="primary-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
<xsd:sequence>
- <xsd:element name="join-column" type="orm:join-column"
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="foreign-key" type="orm:foreign-key"
+ <xsd:element name="foreign-key" type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
- <xsd:element name="join-table" type="orm:join-table"
+ <xsd:element name="join-table" type="orm:join-table"
minOccurs="0"/>
</xsd:choice>
- <xsd:element name="cascade" type="orm:cascade-type"
+ <xsd:element name="cascade" type="orm:cascade-type"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -1935,7 +2018,7 @@
<xsd:annotation>
<xsd:documentation>
- @Target({}) @Retention(RUNTIME)
+ @Target({}) @Retention(RUNTIME)
public @interface QueryHint {
String name();
String value();
@@ -1970,16 +2053,16 @@
</xsd:annotation>
<xsd:sequence>
<xsd:sequence>
- <xsd:element name="primary-key-join-column"
- type="orm:primary-key-join-column"
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="primary-key-foreign-key"
- type="orm:foreign-key"
+ <xsd:element name="primary-key-foreign-key"
+ type="orm:foreign-key"
minOccurs="0"/>
</xsd:sequence>
- <xsd:element name="unique-constraint" type="orm:unique-constraint"
+ <xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="index" type="orm:index"
+ <xsd:element name="index" type="orm:index"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -2034,11 +2117,11 @@
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
- <xsd:element name="entity-result" type="orm:entity-result"
+ <xsd:element name="entity-result" type="orm:entity-result"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="constructor-result" type="orm:constructor-result"
+ <xsd:element name="constructor-result" type="orm:constructor-result"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="column-result" type="orm:column-result"
+ <xsd:element name="column-result" type="orm:column-result"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -2060,9 +2143,9 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="description" type="xsd:string"
- minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="parameter-mode" type="orm:parameter-mode"
+ <xsd:element name="description" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="parameter-mode" type="orm:parameter-mode"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
@@ -2087,9 +2170,9 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="unique-constraint" type="orm:unique-constraint"
+ <xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="index" type="orm:index"
+ <xsd:element name="index" type="orm:index"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
@@ -2122,9 +2205,9 @@
</xsd:annotation>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
- <xsd:element name="unique-constraint" type="orm:unique-constraint"
+ <xsd:element name="unique-constraint" type="orm:unique-constraint"
minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="index" type="orm:index"
+ <xsd:element name="index" type="orm:index"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
@@ -2204,7 +2287,7 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="column-name" type="xsd:string"
+ <xsd:element name="column-name" type="xsd:string"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"/>
diff --git a/src/javax/persistence/spi/PersistenceProvider.java b/src/javax/persistence/spi/PersistenceProvider.java
index 1dbe7ff..1e8e361 100644
--- a/src/javax/persistence/spi/PersistenceProvider.java
+++ b/src/javax/persistence/spi/PersistenceProvider.java
@@ -87,6 +87,28 @@
public void generateSchema(PersistenceUnitInfo info, Map map);
/**
+ * Create database schemas and/or tables and/or create DDL
+ * scripts as determined by the supplied properties.
+ * <p>
+ * Called by the Persistence class when schema generation is to
+ * occur as a separate phase from creation of the entity
+ * manager factory.
+ * <p>
+ * @param persistenceUnitName the name of the persistence unit
+ * @param map properties for schema generation; these may
+ * also contain provider-specific properties. The
+ * value of these properties override any values that
+ * may have been configured elsewhere.
+ * @return true if schema was generated, otherwise false
+ * @throws PersistenceException if insufficient or inconsistent
+ * configuration information is provided or if schema
+ * generation otherwise fails
+ *
+ * @since Java Persistence 2.1
+ */
+ public boolean generateSchema(String persistenceUnitName, Map map);
+
+ /**
* Return the utility interface implemented by the persistence
* provider.
* @return ProviderUtil interface
diff --git a/src/javax/persistence/spi/PersistenceProviderResolverHolder.java b/src/javax/persistence/spi/PersistenceProviderResolverHolder.java
index 976c224..ef76883 100644
--- a/src/javax/persistence/spi/PersistenceProviderResolverHolder.java
+++ b/src/javax/persistence/spi/PersistenceProviderResolverHolder.java
@@ -19,15 +19,12 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
-import java.util.HashMap;
+import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -82,31 +79,15 @@
private static class DefaultPersistenceProviderResolver implements PersistenceProviderResolver {
/**
- * Cached list of available providers cached by CacheKey to ensure
- * there is not potential for provider visibility issues.
+ * Cached list of available providers cached by ClassLoader to ensure
+ * there is not potential for provider visibility issues. A weak map is
+ * used
*/
- private volatile HashMap<CacheKey, PersistenceProviderReference> providers = new HashMap<CacheKey, PersistenceProviderReference>();
-
- /**
- * Queue for reference objects referring to class loaders or persistence providers.
- */
- private static final ReferenceQueue referenceQueue = new ReferenceQueue();
+ private volatile WeakHashMap<ClassLoader, List<PersistenceProvider>> providers = new WeakHashMap<ClassLoader, List<PersistenceProvider>>();
public List<PersistenceProvider> getPersistenceProviders() {
- // Before we do the real loading work, see whether we need to
- // do some cleanup: If references to class loaders or
- // persistence providers have been nulled out, remove all related
- // information from the cache.
- processQueue();
-
ClassLoader loader = getContextClassLoader();
- CacheKey cacheKey = new CacheKey(loader);
- PersistenceProviderReference providersReferent = this.providers.get(cacheKey);
- List<PersistenceProvider> loadedProviders = null;
-
- if (providersReferent != null) {
- loadedProviders = providersReferent.get();
- }
+ List<PersistenceProvider> loadedProviders = this.providers.get(loader);
if (loadedProviders == null) {
Collection<ProviderName> providerNames = getProviderNames(loader);
@@ -135,24 +116,12 @@
log(Level.WARNING, name.toString());
}
}
-
- providersReferent = new PersistenceProviderReference(loadedProviders, referenceQueue, cacheKey);
- this.providers.put(cacheKey, providersReferent);
+ this.providers.put(loader, loadedProviders);
}
return loadedProviders;
}
-
- /**
- * Remove garbage collected cache keys & providers.
- */
- private void processQueue() {
- CacheKeyReference ref;
- while ((ref = (CacheKeyReference) referenceQueue.poll()) != null) {
- providers.remove(ref.getCacheKey());
- }
- }
/**
* Wraps <code>Thread.currentThread().getContextClassLoader()</code> into a doPrivileged block if security manager is present
@@ -278,132 +247,5 @@
return getName() + " - " + getSource();
}
}
-
- /**
- * The common interface to get a CacheKey implemented by
- * LoaderReference and PersistenceProviderReference.
- */
- private interface CacheKeyReference {
- public CacheKey getCacheKey();
- }
-
- /**
- * Key used for cached persistence providers. The key checks
- * the class loader to determine if the persistence providers
- * is a match to the requested one. The loader may be null.
- */
- private class CacheKey implements Cloneable {
-
- /* Weak Reference to ClassLoader */
- private LoaderReference loaderRef;
-
- /* Cached Hashcode */
- private int hashCodeCache;
-
- CacheKey(ClassLoader loader) {
- if (loader == null) {
- this.loaderRef = null;
- } else {
- loaderRef = new LoaderReference(loader, referenceQueue, this);
- }
- calculateHashCode();
- }
-
- ClassLoader getLoader() {
- return (loaderRef != null) ? loaderRef.get() : null;
- }
-
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
- try {
- final CacheKey otherEntry = (CacheKey) other;
- // quick check to see if they are not equal
- if (hashCodeCache != otherEntry.hashCodeCache) {
- return false;
- }
- // are refs (both non-null) or (both null)?
- if (loaderRef == null) {
- return otherEntry.loaderRef == null;
- }
- ClassLoader loader = loaderRef.get();
- return (otherEntry.loaderRef != null)
- // with a null reference we can no longer find
- // out which class loader was referenced; so
- // treat it as unequal
- && (loader != null) && (loader == otherEntry.loaderRef.get());
- } catch (NullPointerException e) {
- } catch (ClassCastException e) {
- }
-
- return false;
- }
-
- public int hashCode() {
- return hashCodeCache;
- }
-
- private void calculateHashCode() {
- ClassLoader loader = getLoader();
- if (loader != null) {
- hashCodeCache = loader.hashCode();
- }
- }
-
- public Object clone() {
- try {
- CacheKey clone = (CacheKey) super.clone();
- if (loaderRef != null) {
- clone.loaderRef = new LoaderReference(loaderRef.get(), referenceQueue, clone);
- }
- return clone;
- } catch (CloneNotSupportedException e) {
- // this should never happen
- throw new InternalError();
- }
- }
-
- public String toString() {
- return "CacheKey[" + getLoader() + ")]";
- }
- }
-
- /**
- * References to class loaders are weak references, so that they can be
- * garbage collected when nobody else is using them. The DefaultPersistenceProviderResolver
- * class has no reason to keep class loaders alive.
- */
- private class LoaderReference extends WeakReference<ClassLoader>
- implements CacheKeyReference {
- private CacheKey cacheKey;
-
- LoaderReference(ClassLoader referent, ReferenceQueue q, CacheKey key) {
- super(referent, q);
- cacheKey = key;
- }
-
- public CacheKey getCacheKey() {
- return cacheKey;
- }
- }
-
- /**
- * References to persistence provider are soft references so that they can be garbage
- * collected when they have no hard references.
- */
- private class PersistenceProviderReference extends SoftReference<List<PersistenceProvider>>
- implements CacheKeyReference {
- private CacheKey cacheKey;
-
- PersistenceProviderReference(List<PersistenceProvider> referent, ReferenceQueue q, CacheKey key) {
- super(referent, q);
- cacheKey = key;
- }
-
- public CacheKey getCacheKey() {
- return cacheKey;
- }
- }
}
}
diff --git a/src/org/eclipse/persistence/javax/persistence/osgi/OSGiProviderResolver.java b/src/org/eclipse/persistence/javax/persistence/osgi/OSGiProviderResolver.java
index ca5ffb1..bb95108 100644
--- a/src/org/eclipse/persistence/javax/persistence/osgi/OSGiProviderResolver.java
+++ b/src/org/eclipse/persistence/javax/persistence/osgi/OSGiProviderResolver.java
@@ -214,4 +214,9 @@
public void generateSchema(PersistenceUnitInfo info, Map map) {
// TODO: JPA 2.1 Functionality
}
+
+ public boolean generateSchema(String persistenceUnitName, Map map) {
+ // TODO Auto-generated method stub
+ return false;
+ }
}